最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 探究JavaScript中的this为啥东指西指

    正文概述 掘金(_poppy)   2021-04-23   335

    js中的this可谓是花样百出,在不同的环境、不同的作用下表现是不同的,下面我们就来探究一下js中this的用法和指向问题

    1.首先从最简单的开始说,普通的函数中this的指向

    function test() {
        this.a = 1;
        console.log(this);
        console.log(this.a);
    }
    
    test();
    

    结果

    Window
    1
    

    可以看出this是指向window的,函数中this.a 相当于window.a

    但如果在js的严格模式下,可就不一样了,我们在函数中加一段"use strict"

    
    function test() {
        'use strict';
        console.log(this);
    }
    
    test();
    

    结果

    undefined
    

    结果为undefined 所以说在严格模式下,普通函数执行的时候内部this不指向谁

    2.对象中的方法this指向

    var obj = {
        a: 1,
        test: function () {
            console.log(this);
            console.log(this.a);
        }
    }
    obj.test();
    

    结果

    {a: 1, test: ƒ}
    1
    

    那我们就明确了对象里面的方法是可以通过this访问到对象本身的,从而就可以通过this.** 访问到对象里面的属性和方法

    3.构造函数中this的指向

    function Test(a) {
        this.a = a;
        console.log(this.a);
        console.log(window.a);
    }
    
    var test = new Test(1);
    

    结果

    1
    undefined
    

    window.a为undefined,说明在构造函数在被实例化之后,this不会指向window,我们在构造函数中加一句console.log(this)
    结果

    {a: 1}
    

    由此可以看构造函数在被实例化之后,其中this指向被实例化出来的对象
    那么构造函数原型上的方法this指向什么呢?
    我们在原型是定义一个方法

    Test.prototype.say = function () {
        console.log(this.a); // 1
    }
    test.say();
    

    能正常的打印出 a 的值,也就证明了一点:原型上方法内部的this依然指向构造函数实例化出来的对象

    4.事件处理函数中this的指向

    在页面中创建一个按钮

    <button id="btn">CLICK</button>
    

    当他点击的时候,给它绑定一个事件处理函数

    var oBtn = document.querySelector('#btn');
    oBtn.addEventListener('click', function () {
        console.log(this)
    }) 
    

    结果

    <button id="btn">CLICk</button>
    

    由此得出事件处理函数内部的this指向绑定元素的本身

    5.call/apply/bind 改变this的指向

    call:函数名.call(this, arg1, arg2, ...),第一个参数用来指定函数内部this的指向,后面的参数是函数执行时所需要的实参

    var obj = {
        a: 1,
        b: 2
    }
    
    function test(c, d) {
        console.log(c + ',' + d);
        console.log(this.a);
    }
    
    test.call(obj, 10, 100);
    

    结果:

    10, 100
    1
    

    apply:函数名.call(this, [arg1, arg2, ...]),与call不同的是把实参放到一个数组中传入

    var obj = {
        a: 1,
        b: 2
    }
    
    function test(c, d) {
        console.log(c + ',' + d);
        console.log(this.a);
    }
    
    test.apply(obj, [10, 100]);
    

    结果:

    10, 100
    1
    

    bind:bind用法和call一样,只是他不像call/apply会立即执行,而是返回一个新的函数

    var obj = {
        a: 1,
        b: 2
    }
    
    function test(c, d) {
        console.log(c + ',' + d);
        console.log(this.a);
    }
    
    const _test = test.bind(obj, 10, 100);
    _test();
    

    结果:

    10, 100
    1
    

    6.箭头函数中this的指向

    上面我们说到普通函数可以通过call/apply/bind改变this的指向 ,但是如果在es6的箭头函数中,是否还能像上面一样改变this的指向呢?不妨来试一下

    var obj = {
        a: 1,
        b: 2
    }
    var a = 100
    
    const test = () => {
        console.log(this.a);
    }
    test.call(obj);
    

    结果:

    100
    

    发现并没有打印出 1 ,所有得出一个结论:箭头函数忽略任何形式的this指向的改变。
    那么箭头函数中的this到底指向什么呢?我们先看几个例子之后再进行总结:

    • 在一个对象中添加一个方法,这个方法是一个箭头函数
    var obj = {
        a: 1,
        test: () => {
            console.log(this)
        }
    }
    obj.test();
    

    结果

    Window // 指向 window
    

    由此可以知道箭头函数中的this不是谁绑定就指向谁

    • 在对象的一个方法中再定义一个箭头函数,并执行
    var obj = {
        a: 1,
        test: function () {
            var t = () => {
                console.log(this)
            }
            t();
        }
    }
    obj.test();
    

    结果

    {a: 1, test: ƒ} // 指向 obj
    
    • 对象的方法为一个箭头函数
    var obj = {
        a: 1,
        test: () => {
            var t = () => {
                console.log(this)
            }
            t();
        }
    }
    obj.test();
    

    结果

    Window // 指向 window
    
    • 在闭包函数中定义一个箭头函数
    var obj = {
        a: 1,
        test: function () {
            var t1 = function () {
                var t2 = () => {
                    console.log(this);
                }
                t2();
            }
            t1();
        }
    }
    obj.test();
    

    结果

    Window // 指向 window
    
    • 再看一个例子
    var obj = {
        a: 1,
        test: function () {
            var t1 = () => {
                var t2 = () => {
                    console.log(this);
                }
                t2();
            }
            t1();
        }
    }
    obj.test();
    

    结果

    {a: 1, test: ƒ} // 指向 obj
    

    由以上几个例子我们可以得出结论:箭头函数的this指向外层作用域的this指向,但是外层不能是箭头函数,也就是说箭头函数this的指向就是外层非箭头函数this的指向


    所以我们在分析this的指向的时,不能片面的认为被谁调用就指向谁,还要根据其所处的环境进行进一步分析


    起源地下载网 » 探究JavaScript中的this为啥东指西指

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元