箭頭函數中的this指向


最近做的項目中遇到了在箭頭函數里使用this時報錯的問題,把箭頭函數的寫法改成function()后,this的指向才達到預期。關於這個問題值得研究一下。

在箭頭函數出現之前的ES5時代,this指向它的調用者。是哪個對象調用了這個屬性或方法,this就指向這個對象。這有點像“我”這個人稱代詞,是從誰的嘴里說出了“我”,這個“我”就指代了誰。

一個簡單的例子:

// 用var定義的變量,this指向window
// 調用sayName()等於調用this.sayName()等於調用window.sayName()
var name = 'window';
var sayName = function(){
  return this.name
}
console.log(sayName()) 			//window
console.log(this.sayName()) 	//window
console.log(window.sayName()) 	//window

// 用obj調用的sayName方法,其中this指向調用它的obj
var obj = {
  name : 'obj',
  sayName : function(){
	return this.name
  }
}
console.log(obj.sayName()) 	    //obj

后來ES6規范中的箭頭函數里面的this是在定義它時綁定的,指向它的父級作用域,而不是調用它對象,這個this的指向是不能通過call和apply改變的。

箭頭函數在對象字面量中的this指向:

// 用var定義的變量,this指向window
// 雖然展現結果和上例一樣,但是this的指向綁定的時機是有區別的,箭頭函數在定義時已經綁定,普通函數只會在調用時確定
var name = 'window';
var sayName = () => {
  return this.name;			//this指向window
};
console.log(sayName());         //window
console.log(this.sayName());    //window
console.log(window.sayName());  //window

//同樣用obj調用的sayName方法,this指向父級作用域window
var obj = {
  name: 'obj',
  sayName: () => {
    return this.name;  
  }
};
console.log( obj.sayName() );     //window
console.log( obj.sayName() === window.sayName() );     //true

這是箭頭函數this指向在對象字面量中的行為。多說一句,在用對象實例調用時會有所差別。

看下面的例子:

var name = 'window'
    
function Obj(name){     //構造函數Obj
  this.name = name;
  this.s1 = function(){
    return this.name;   //普通函數方法,this指向Obj
  }
  this.s2 = () => {
    return this.name;   //箭頭函數方法,this還是指向Obj,因為構造函數function Obj(name)形成了一級作用域
  };
}
Obj.prototype.s3 = function(){
  return this.name;     //原型鏈上的普通方法,this指向實例obj1的構造函數Obj
}
Obj.prototype.s4 = () => {
  return this.name;     //原型鏈上的箭頭函數,定義它的時候,這個箭頭函數的父級作用域是window
}

//實例化對象
const obj1 = new Obj('obj');

console.log(obj1.s1());  //obj
console.log(obj1.s2());  //obj
console.log(obj1.s3());  //obj
console.log(obj1.s4());  //window
  • s2()箭頭函數會去找定義它時的父級作用域,因為構造函數Obj也是個函數,它會形成自己的作用域。定義s2()的時候父級作用域變成了構造函數Obj所在的域
  • s4()和s2()的區別是s4()掛載到構造函數的原型上了,定義s4()的時候,這個箭頭函數的父級作用域是window,所以用實例調用方法會輸出了 'window'

最后總結:在對象字面量中和在構造函數的原型上使用箭頭函數,this指向不是我們預期的結果,在這兩種情況下使用箭頭函數要慎重。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM