前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS进阶第一课【this,严格模式,闭包】

JS进阶第一课【this,严格模式,闭包】

原创
作者头像
申小兮
发布2023-04-27 19:48:28
3060
发布2023-04-27 19:48:28
举报
文章被收录于专栏:前端开发基础前端开发基础

一、this

解析器在每次调用函数的时候都会向函数内部传递一个隐含的参数,即this

该对象:函数执行上下文,根据函数调用的方式不同,this的指向也就不同

1、普通函数:指向window

2、对象方法:指向该对象

3、构造函数:指向实例对象(原型对象里面的方法也是指向实例)

代码语言:javascript
复制
<script>
    // 普通函数
    var test = function(){
        console.log("this",this);
    }
    test();//window
 
    // 对象方法
    var obj ={
        say:test
    }
    obj.say();//obj
 
    // 构造函数
    function Person(){
        this.create = test
    }
    var p1 = new Person()
    p1.create();//Person
</script>

 4、事件绑定:绑定事件的对象

代码语言:javascript
复制
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    // 事件
    var list = document.querySelectorAll('li');
    for(var i = 0;i<list.length;i++){
        list[i].onclick = function(){
            console.log("this",this);//li
        }
    }
</script>

 5、定时器:指向window

代码语言:javascript
复制
<script>
    // 定时器
    setTimeout(function(){
        console.log("this",this);//window
    })
</script>

 6、立即执行函数:指向window

代码语言:javascript
复制
<script>
    // 立即执行函数
    (function(){
        console.log("this",this);//window
    })()
</script>

JavaScript会提供一些函数方法来帮助我们更优雅地处理函数内部this指向问题,常用的有:call()、apply()、bind()

二、call()

1、格式

调用函数名().call(指向谁,参数1,参数2...)

2、作用

(1)可以直接调用函数

(2)可以改变函数this指向

代码语言:javascript
复制
<script>
    var x=10;
    var y=20;
 
    var count = {
        x:1,
        y:2,
    }
 
    function total(a){
        console.log("this",this);
        console.log(a);
        console.log(this.x+this.y);
    }
 
    total(100);
    total.call(count,100);
</script>

 (3)可以实现继承(构造函数)

代码语言:javascript
复制
<script>
    function Father(uname){
        console.log("Father",this);
        this.userName = uname;
    }
 
    function Son(uname){
        console.log("Son",this);
        Father.call(this,uname);
    }
 
    var p1 = new Son('张三');
    console.log(p1);
 
</script>

三、apply()

1、格式

调用函数().apply(thisArg,[arhsArray])

(1)thisArg:在函数运行时的this指向

(2)arhsArray:要传递的值(必须包含在数组里面)

(3)返回值就是函数(函数的返回值),因为是在调用函数

2、作用

(1)与call()相同,可以直接调用函数,可以改变函数this指向

(2)参数必须是数组

代码语言:javascript
复制
<script>
    var x=10;
    var y=20;
 
    var count ={
        x:1,
        y:2,
    }
 
    function total(a,b){
        console.log("this",this);
        console.log(a,b);
        console.log(this.x+this.y);
    }
 
    total(100,200);
    total.apply(count,[100,200]);
    
</script>

(3)常用于借助属性的内置函数求最大、最小值

代码语言:javascript
复制
<script>
    var arr =[10,5,6,71,4,61];
    console.log(Math.max(10,5,6,71,4,61));
    console.log(Math.max.apply(Math,arr));
</script>

 3、拓展

(1)...arr:扩展,可以把整个数组拆出来

代码语言:javascript
复制
<script>
    var arr =[10,5,6,71,4,61];
    console.log(Math.max(...arr));
</script>

 四、bind()【常用】

1、格式

函数名.bind(指向的对象,参数1,参数2...)

2、作用

(1)不会调用函数,但是能改变函数内部的this指向

(2)返回直接对原函数的拷贝

代码语言:javascript
复制
<script>
    var x=10;
    var y=20;
 
    var count ={
        x:1,
        y:2,
    }
 
    function total(a){
        console.log('this',this);
        console.log(a);
        console.log(this.x+this.y);
    }
 
    total(100);
    console.log(total.bind(count,10));
    var f = total.bind(count,10);
    f();
</script>

(3)函数不需要立即调用,又需要改变函数内部的this指向

3、代码例子:发送验证码(点击按钮后禁用3秒,才可以再点击使用)

代码语言:javascript
复制
<button>发送验证码</button>
<script>
    var btn = document.querySelector("button");
    btn.onclick = function(){
        console.log("this",this);
        this.disabled = true;
        setTimeout(function(){
            console.log("this",this);
            this.disabled = false;
        }.bind(this),3000)
    }
</script>

call()、apply()、bind()总结

1、相同点:都可以改变函数内部的this指向

2、区别点:

(1)call和apply都会调用函数,但是bind不会调用函数

(2)call和apply传递参数不一样

①call传递参数形式arg1,arg2

②apply必须是数组形式[arg1,arg2]

3、主要应用场景

(1)call常用于继承,如子级函数需要获取父级函数的参数

(2)apply常用于与数组有关,如借助数学内置对象,实现求数组最大、最小值

(3)bind常用于不调用函数又想改变函数this指向,如定时器里的this指向


五、严格模式

JavaScript除了提供正常模式外,还提供了严格模式(strict mode),es5的严格模式是采用具有限制性的

1、目的

(1)消除一些语法的不合理,不严谨,减少一些怪异行为,如:没有声明变量,就去使用

(2)消除代码运行的一些不安全之处,保证代码运行的正常,增加代码运行的安全性

(3)提高编译器的效率,提高运行的速度

(4)关键字不能做变量名,如:class、export、extends、import、super

2、开启严格模式

(1)语句:use strict

(2)为所有语句开启

①未开启时

代码语言:javascript
复制
<script>
    a = 1;
    console.log(a);
</script>

②开启时

代码语言:javascript
复制
<script>
    "use strict";
    a = 1;
    console.log(a);
</script>

(3)为函数内部开启

代码语言:javascript
复制
<script>
    b = 1;
    console.log(b);
    (function(){
        "use strict";
        a = 1;
        console.log(a);
    })()
</script>

 3、严格模式的变化

(1)变量必须先声明再赋值

(2)this指向的改变,全局作用域中的函数,指向变成了undefined而不是原来的window了

①未开启时

代码语言:javascript
复制
<script>
    var test = function(){
        console.log("this",this);
    }
    test();
</script>

②开启时

代码语言:javascript
复制
<script>
    "use strict";
    var test = function(){
        console.log("this",this);
    }
    test();
</script>

(3)构造函数必须加new调用,否则this会报错

①未开启时

代码语言:javascript
复制
<script>
    function Person(){
        this.sex = '女';
    }
    Person();
    console.log(window.sex);
</script>

 ②开启,未new时

代码语言:javascript
复制
<script>
    "use strict";
    function Person(){
        this.sex = '女';
    }
    Person();
    console.log(window.sex);
</script>

③开启,new时

代码语言:javascript
复制
<script>
    "use strict";
    function Person(){
        this.sex = '女';
    }
    var sxx =new Person();
    console.log(sxx.sex);
</script>

六、闭包【面试官常问:什么是闭包?🧐】

1、概念:有权访问另一个函数作用域中的变量的函数

一个作用域可以访问另一个作用域内部的局部变量

2、作用

(1)延伸作用域范围

代码语言:javascript
复制
<script>
    function fn1(){
        var num =10;
        function fn2(){
            console.log(num);
        }
        fn2()
    }
    fn1()
</script>

②立即执行函数(小闭包):在循环的点击事件里面,立即执行函数里面的所有函数都可以拿到需要的变量

未使用立即执行函数小闭包

代码语言:javascript
复制
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    var list = document.querySelectorAll('li');
    for(var i = 0; i<list.length;i++){
        list[i].onclick = function(){
            console.log(i);//无论点击第几个li,均获取的是i=3,这是错误的
        }
    }
</script>

 使用立即执行函数小闭包后

代码语言:javascript
复制
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    var list = document.querySelectorAll('li');
    for(var i = 0; i<list.length;i++){
        (function(i){
            list[i].onclick = function(){
                console.log(i);//这样获取的i才是正确的对应li下标
            }
        })(i)
    }
</script>

(2)避免变量被资源回收机制销毁

代码语言:javascript
复制
<script>
    function add(){
        var a = 0;
        return function addCount(){
            a++;
            console.log(a);
        }
    }
    var count = add();
    count();//1
    count();//2
</script>

3、缺点

(1)函数局部变量一直存在,占用内存

(2)任意造成内存泄露

4、删除闭包

代码语言:javascript
复制
count = null;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、this
    • 1、普通函数:指向window
      • 2、对象方法:指向该对象
        • 3、构造函数:指向实例对象(原型对象里面的方法也是指向实例)
          •  4、事件绑定:绑定事件的对象
            •  5、定时器:指向window
              •  6、立即执行函数:指向window
              • 二、call()
                • 1、格式
                  • 2、作用
                  • 三、apply()
                    • 1、格式
                      • 2、作用
                        •  3、拓展
                        •  四、bind()【常用】
                          • 1、格式
                            • 2、作用
                              • 3、代码例子:发送验证码(点击按钮后禁用3秒,才可以再点击使用)
                                • call()、apply()、bind()总结
                                  • 1、相同点:都可以改变函数内部的this指向
                                  • 2、区别点:
                                  • 3、主要应用场景
                                  • 1、目的
                                  • 2、开启严格模式
                                  •  3、严格模式的变化
                                  • 1、概念:有权访问另一个函数作用域中的变量的函数
                                  • 2、作用
                                  • 3、缺点
                                  • 4、删除闭包
                              • 五、严格模式
                              • 六、闭包【面试官常问:什么是闭包?🧐】
                              相关产品与服务
                              验证码
                              腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档