this指向问题

122 阅读2分钟

this 的四个绑定规则

  • 独立调用(绑定),this 指向全局;

  • 隐式绑定,this 指向 . 前面的对象;

        var n = 'xdh';
        var obj = {
            n: 'ht',
            fn: f
        }
        function f(){console.log(this)}
        obj.fn() // obj
    
  • 显式绑定,this 指向显式指定的对象(通过调用call/apply/bind);

        var n = 'xdh';
        var obj = {
            n: 'ht',
            fn: f
        }
        function f(){console.log(this)}
        f.call(obj) // obj
        f.call(null) // window
    

    注意:call/apply/bind 传入null/undefined 时,自动将 this 绑定成全局。

  • new 关键字绑定,this 指向 new 出来的这个实例。

        function F(name, age){
            this.name = name
            this.age = age
            console.log(this)
        }
        var f = new F('xdh', 18)  // F {name: 'xdh', age: 18}
    

一些特殊情况:

  • call/apply/bind 传入null/undefined 时,自动将 this 绑定成全局;
  • 间接函数引用;

有括号操作符调用,且括号里面有赋值操作,或者括号里面包含逗号分隔的多项的情况,会把 this 绑定为全局。

    var obj1 = {
        name: 'obj1',
        foo: function(){console.log(this)}
    }
    var obj2 = {name: 'obj2'}; // 注意这里需要分号不然会报错,因后面是个括号
    (obj2.bar = obj1.foo)() // window 赋值操作后会返回赋值的这个函数,再调用就是单独调用了
    (16, obj1.foo)() // 这种括号里面包含多项的会自动把 this 指向改变成全局
  • 箭头函数没有 thisarguments

它的this只跟定义时候的上层作用域里的this有关,上层的this是什么就是什么;call/apply/bind 对箭头函数不起效,new 关键字也不起效。

    // 返回普通函数的情况
    var name = 'window'
    var obj = {
        name: 'obj',
        foo: function(){
            return function(){console.log(this.name)}
        }
    }
    var obj2 = {name: 'obj2'}
    obj.foo()() // 'window' 调用的时候是独立调用的
    obj.foo.call(obj2)() // 'window' call只是把foo的this改变了,返回的函数还是独立调用
    obj.foo().call(obj2) // 'obj2' 显示绑定改变了this

    // 返回箭头函数的情况
    var name = 'window'
    var obj = {
        name: 'obj',
        foo: function(){
            return () => console.log(this.name)
        }
    }
    var obj2 = {name: 'obj2'}
    obj.foo()() // 'obj' 箭头函数定义的地方的this是obj
    obj.foo.call(obj2)() // 'obj2' 
    obj.foo().call(obj2) // 'obj' call/apply/bind 对箭头函数不起效

几个绑定规则的优先级

new > 显式 > 隐式 > 独立调用

参考链接:coderwhy:彻底搞懂this