es5和es6this的区别

838 阅读2分钟

区别: 

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);
}