今天抽空对this绑定进行了整理:
this绑定规则优先级
上面也说过,这里在重复一下。优先级是这样的,以按照下面的顺序来进行判断:
1.函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象;
var a = 2;
function foo(a){
this.a = a;
}
let bar1 = new foo(3);
console.log(bar1.a); // ?
let bar2 = new foo(4);
console.log(bar2.a); // ?
答案是:3,4
2.函数是否通过call、apply(显式绑定)或者硬绑定调用?如果是的话,this绑定的是 指定的对象;
function foo(){
console.log(this.a);
}
var a = 2;
var obj1 = {
a : 3,
foo : foo
}
var obj2 = {
a : 4,
obj1 : obj1
}
foo.call(obj1); // ?
foo.call(obj2); // ?
答案是:3,4
3.函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this绑定的是那个上下文对象;
function foo(){
console.log(this.a);
}
var a = 2;
var obj = {
a : 3,
foo : foo
}
obj.foo(); // ?
答案是:3
4.如果都不是的话,使用默认绑定。如果在严格模式下,就绑定undefined,否则绑定到全局对象。
function foo(){
console.log(this.a);
}
var a = 2;
foo(); // 打印结果?
答案是:2
另外要注意的是箭头函数中的 this:
- 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this;
- 箭头函数里的this指向无法被call,apply,bind 改变;
- 箭头函数this的指向性是函数被创建时绑定的而不是调用的时候绑定,this的指向就是绑定时所在作用域并且不会因为被怎么调用而改变指向,并不会指向运行时所在的作用域
-
var obj = { foo(){ console.log(this); }, bar : ()=>{ console.log(this); } } obj.foo(); // { foo: foo(), bar: bar() } obj.bar(); // window