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 指向改变成全局
- 箭头函数没有
this和arguments
它的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