箭頭函式中的this

水手發表於2019-03-18

ES6中新增了箭頭函式這種語法,箭頭函式以其簡潔性和方便獲取this的特性。下面來總結一下他們之間的區別:

普通函式下的this:

  • 在普通函式中的this總是代表它的直接呼叫者,在預設情況下,this指的是window,
  • 在嚴格模式下,沒有直接呼叫者的函式中的this是 undefined使用
  • call,apply,bind(ES5新增)繫結的,this指的是 繫結的物件

箭頭函式中的this:

  • 箭頭函式沒有自己的this, 它的this是繼承而來; 預設指向在定義它時所處的物件(宿主物件),
  • 而不是執行時的物件, 定義它的時候,可能環境是window,也有可能是其他的。
普通函式
function test() { 
   console.log(this);  
 }  
 test();  //window

複製程式碼

test是一個全域性函式,也就是掛載在window物件下的 test()等價於window.test();

var obj = {  
   func: function () {  
     console.log(this); 
     setTimeout(function () {   
       console.log(this);
     },0);   
   }  
 }  
 obj.func(); 
// obj,此時的this是obj物件    
// window
複製程式碼

say的宿主環境是obj,所以say裡面的this是obj。 定時器中的函式,由於沒有預設的宿主物件,所以this指向window 嚴格模式下的this:

function test() {  
   'use strict';  
   console.log(this); 
 }  
 test(); 
 //undefined   
複製程式碼
嚴格模式

在嚴格模式下,沒有直接呼叫者的函式中的this是 undefined

"use strict";   
    var obj={   
      say:function(){   
        console.log(this);
      }  
    };  
obj.say();  
//obj    

複製程式碼

有直接呼叫者的this是它的呼叫者

箭頭函式
var obj = {  
   say: function () {  
     setTimeout(() => {  
       console.log(this);
     });  
   }  
 }  
 obj.say(); 
 // obj    
複製程式碼

此時的 this繼承自obj, 指的是定義它的物件obj, 而不是 window

var obj = {  
 say: function () {  
   var f1 = () => {  
     console.log(this); // obj  
     setTimeout(() => {  
       console.log(this); // obj  
     })  
   }  
   f1();  
 }  
}   
obj.say() 
複製程式碼

因為f1定義時所處的函式 中的 this是指的 obj, setTimeout中的箭頭函式this繼承自f1,所以不管有多層巢狀,都是 obj

var obj = {  
 say: function () {  
   var f1 = function () {  
     console.log(this);  
     setTimeout(() => {  
       console.log(this); 
   })  
   };  
   f1();  
 }  
}  
obj.say()
// window, f1呼叫時,沒有宿主物件,預設是window 
// window  
複製程式碼

箭頭函式沒有this的繫結,必須通過查詢作用鏈來決定其值。如果箭頭函式被非箭頭函式包含,則this繫結的是最近以層的非箭頭函式的this;否則。this的值會被設定為undefined。 箭頭函式在定義的時候它所處的環境相當於是window, 所以在箭頭函式內部的this函式window

相關文章