眾所周知箭頭函數(shù)的使用主要是為了this指針不因為調(diào)用對象的不同而發(fā)生改變丈咐。但是有些情況下回發(fā)現(xiàn)箭頭函數(shù)的this并不是我們想的那樣瑞眼,使用靜態(tài)的上層作用域的this。
今天我總結一下箭頭函數(shù)的this到底是怎么回事棵逊。什么時候會因為調(diào)用對象的不同而改變什么時候不會伤疙。
http://www.reibang.com/p/c1ee12a328d2
不是很清楚箭頭函數(shù)的基本用法先了解一下。
今天我給點擊事件綁定函數(shù)時嘗試了箭頭函數(shù)辆影。
<button id="clickMe">click me</button>
let obj={
clickBind:function () {
let arrow=()=>{
console.log(this);
};
arrow();
}
};
let btn=document.getElementById("clickMe");
btn.addEventListener("click",obj.clickBind);
表面上看起來沒有什么問題徒像,使用箭頭函數(shù),應該輸出的this是上層作用域也就是clickBind的this,也就是obj蛙讥。
但是實際上的輸出是dom元素<button id="clickMe">click me</button>
這說明箭頭函數(shù)的this并不是我們想象得那么靜態(tài),確實發(fā)生了變化锯蛀。那么這是怎么一回事呢。
其實是箭頭函數(shù)沒有自己的this次慢,使用的是上層作用域的this谬墙,在這個例子中arrow使用的是clickBind的this。clickBind這個obj對象中的普通函數(shù)會因為調(diào)用對象的不同this指針也同经备。也就是說箭頭函數(shù)的this會根據(jù)上層作用域的this的變化而變化
比如說下面這個例子
let a={
name:"a",
f1:function(){
$(".container .submit").click(()=>{
console.log(this.name);
});
}
};
let b={
name:"b",
f1:function(){
$(".container .submit").click(()=>{
console.log(this.name);
});
}
};
a.f1.call(b);//b
b通過call調(diào)用a的f1方法拭抬,f1中一個dom通過箭頭函數(shù)綁定了一個事件。箭頭函數(shù)的this是f1的this侵蒙。那么b調(diào)用a中的f1方法造虎,f1的this指向b,f1中的箭頭函數(shù)的this也指向b。所以輸出b.name纷闺。
既然箭頭函數(shù)的this也會變化算凿,那么到底怎么辦?this怎么樣才不會隨著調(diào)用對象而改變犁功。
其實只要是保證箭頭函數(shù)的上一層函數(shù)的this不會改變就好了氓轰。
比如說
let obj={
clickBind:function () {
let arrow=()=>{
console.log(this);
};
arrow();
}
};
let btn=document.getElementById("clickMe");
btn.addEventListener("click",obj.clickBind);
保證只有obj會調(diào)用clickBind,別的對象都不調(diào)用他,obj中clickBind方法的箭頭函數(shù)永遠指向obj浸卦。
所以不能給dom綁定clickBind方法署鸡,那么為了使綁定事件的this指向obj,就放在obj的clickBind方法內(nèi)部。
let btn=document.getElementById("clickMe");
let obj={
clickBind:function () {
let arrow=()=>{
console.log(this);//obj對象
};
btn.addEventListener("click",arrow);
}
};
obj.clickBind();
總結
像addEcentListener,setTimeOut,Promise.then這種傳遞一個函數(shù)作為回調(diào)的情況如果想使用一個靜態(tài)的一個對象的this限嫌,那么就使用箭頭函數(shù)靴庆,并且寫在這個對象的任意方法的內(nèi)部,并且保證這個方法不被別的對象調(diào)用怒医。