daJS的this一共可分为四类。分别是:
- 默认绑定;
- 隐式绑定(上下文绑定);
- 显式绑定;
- new绑定;
优先级:new绑定>显示绑定>隐式绑定>默认绑定
那么什么是默认绑定、隐式绑定、显式绑定、new绑定呢?下面开始看例子:
var name = 'jack';
function person() {
console.log(this.name); //jack
}
person();
打印jack,这是因为person函数的调用环境是全局,也就是window,这就是默认绑定。需要注意的是,这是在非严格情况下,若是在严格情况下,this指向undefined。
var name = 'blob';
function foo(){
console.log(this.name);
}
var obj = {
name: 'jack',
foo:foo,
}
obj.foo(); //jack
var foo = obj.foo;
foo();//blob
打印jack是因为this的调用环境是在obj内,而这个时候的this是隐式绑定;打印blob是因为foo函数的调用环境是全局,也就是指window,这就是默认绑定了。
var name = 'blob';
function foo(){
console.log(this.name);
}
foo();//blob
var obj = {
name: 'jack',
}
foo.call(obj);
foo();//jack
打印blob这个很好理解,它就是默认绑定。打印jack就是把foo函数通过call把它的this改为指向了obj。
function foo(name){
this.name = name;
}
var obj = {
foo:foo
}
obj.foo('jack');
console.log(obj.name);//jack
var test = new obj.foo('blob');
console.log(test.name);//blob
打印jack,这里就是隐式绑定;打印blob,这里是new绑定。在这里也可以看出new绑定优先级大于隐式绑定。
总结一下:默认绑定大多是在独立函数中调用;隐式绑定大多是指对象的某个属性是一个函数;显示绑定一般是指通过bind、call、applay来强制改变this;new绑定是通过new关键字来改变this指向的。
在ES6中引入了箭头函数,需要注意的是箭头函数内部没有this,它里面的this继承父级的this,另外箭头函数不能使用new、也不能使用bind、call和applay。
至于其他比较复杂的case,后续会进行补充