区别:
es5:普通函数中的this总是指向它的直接调用者;如果没有调用者在严格模式下this是 undefined,在非严格模式下this指向window
es6:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
其次,箭头函数都没有自己的this,它们的this就是最外层函数的this。
var val = 1;
var obj = {
val: 2,
fun1: function () {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
},
fun2: () =>{
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
},
fun3: function(){
(()=>{
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
})();
},
fun4: () =>{
(()=>{
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
})();
}
};
obj.fun1();//2,4
var fun = obj.fun1;
fun();//8,8
obj.fun2();//32,32
obj.fun3();//64,8
obj.fun4();//256,256解析:以下两点是贯穿整个执行过程的重点
(1)、 val变量在没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量
即 val *=2 就是 window.val *= 2;
(2)、箭头函数,都没有自己的this,它们的this就是箭头函数所在对象的所在作用域里的this。
1、obj.fun1();
fun1()被obj直接调用,所以fun1里面的this.val中的this指的是obj,this.val就是obj.val;
obj.fun1()执行,
this.val=obj.val*2=2*2=4;
val==window.val=1*2=2;
2、fun();
上面的1执行完后window.val=2,obj.val=4;
由于var fun = obj.fun1;那么
fun=function () {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
}
fun();
fun自执行,前面没有前缀,相当于window.fun(),所以fun()里面的this指向window,
this.val相当于window.val
fun()执行,
this.val*2==window.val*2=2*2=4,
val==window.val=4*2=8;
由于this指向window,所以 console.log(this.val)时,this.val==window.val==val=8;
3、fun2();
上面的2执行完后,window.val=8,obj.val=4;
fun2(),因为fun2是箭头函数,fun2所在对象是obj,而obj所在的作用域是window,所以fun2里的this指向window,
fun2()执行,
this.val*2==window.val*2=8*2=16;
val==window.val=16*2=32;
由于this指向window,所以 console.log(this.val)时,this.val==window.val==val=32;
4、fun3();
上面的3执行完后,window.val=32,obj.val=4;
fun3(),因为fun3里面的匿名函数是箭头函数,箭头函数所在对象是函数fun3,而fun3所在的作用域是obj,所以fun3里的匿名函数的this指向obj,
fun3()执行,
this.val*2==obj.val*2=4*2=8;
val==window.val=32*2=64;
由于this指向obj,所以此时this.val==obj.val=8;
5、fun4();
上面的4执行完后,window.val=64,obj.val=8;
fun4(),因为fun4是箭头函数,fun4所在对象是obj,而obj所在的作用域是window,所以fun4里的this指向window,
fun4()执行,
this.val*2==window.val*2=64*2=128;
val==window.val=128*2=256;
由于this指向window,所以 console.log(this.val)时,this.val==window.val==val=256;
es5与es6的转化
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}