哪些情況不能使用this
少年离福,不要濫用箭頭函數(shù)啊
箭頭函數(shù)的this是根據(jù)外層(函數(shù)或者全局)作用域來決定this年鸳,箭頭函數(shù)會捕捉調(diào)用父函數(shù)時候父函數(shù)的this
//eg1
var x = 10;
var demo2 = {
x : 1,
test1 : () => { console.log(this.x); },
};
demo2.test1(); // 10
上面代碼的結(jié)果為什么是10妖枚,test1不是在demo2這個對象內(nèi)嗎运提?所以不應該this就指向demo2了嗎鳍寂?以上代碼中改含,箭頭函數(shù)中的this并不是指向aa這個對象。對象aa并不能構(gòu)成一個作用域迄汛,所以再往上到達全局作用域捍壤,this就指向全局作用域。因為test1沒有父函數(shù)鞍爱,直接就是全局作用域鹃觉。所以這里的this指向window。
//eg2
var id = '888'
var handler = {
id: '123456',
init: function() {
(()=>{
console.log(this.id)
})()// 讓箭頭函數(shù)自執(zhí)行
},
init1: function() {
(function(){
(()=>{console.log(this.id)})()
})() // 匿名函數(shù)自執(zhí)行的內(nèi)部是箭頭函數(shù)的自執(zhí)行
},
};
handler.init()//123456
var aa = handler.init
aa() // 888
handler.init1()//888
eg2的話init創(chuàng)建了一個作用域睹逃。箭頭函數(shù)會捕捉調(diào)用init時候init內(nèi)的this盗扇。handler.init
調(diào)用時候init內(nèi)的this指向handler對象祷肯。var aa = handler.init; aa()
這樣子的話調(diào)用init是window
。所以值是888疗隶。handler.init1()
的值為什么是888呢佑笋?因為init1內(nèi)部是個匿名函數(shù)自執(zhí)行。自執(zhí)行內(nèi)部才是箭頭函數(shù)斑鼻。所以這樣子看來蒋纬,箭頭函數(shù)的外部是個匿名函數(shù)自執(zhí)行,而自執(zhí)行函數(shù)的this指向window
。所以init1的值為888
- 箭頭函數(shù)適合于無復雜邏輯或者無副作用的純函數(shù)場景下坚弱,例如用在map蜀备、reduce、filter的回調(diào)函數(shù)定義中荒叶;
- 不要在最外層定義箭頭函數(shù)碾阁,因為在函數(shù)內(nèi)部操作this會很容易污染全局作用域。最起碼在箭頭函數(shù)外部包一層普通函數(shù)停撞,將this控制在可見的范圍內(nèi);
1
$("#desktop a img").each(function(index){
alert($(this));
alert(this);
} //這里的this就是 $("#desktop a img"). 誰調(diào)用就是誰 jquery庫把this進行了包裝
2
$(".myMenuItem").mouseover( () => {
console.log("$(this)",$(this))
} //這里的$(this)也是jquery對象但是指向整個react 悼瓮,取決于箭頭函數(shù)在哪兒定義戈毒,而非箭頭函數(shù)執(zhí)行的上下文環(huán)境。這里相當于也是回調(diào)横堡。箭頭函數(shù)本身是沒有this的所以就向上找一層
匿名函數(shù)自執(zhí)行埋市,setTimeout等中的this指向全局
JavaScript 環(huán)境中內(nèi)置的 setTimeout() 函數(shù)實現(xiàn)和下面的偽代碼類似:
function setTimeout(fn,delay) { // 等待 delay 毫秒
fn(); // <-- 調(diào)用位置! 這里就是單純的函數(shù)調(diào)用,所以指向全局
}
function Bue() {
(function() {
debugger;
console.log('this', this.init) 所以這里的this是window this.init為undefined命贴。并不是你所想象的this指向app實例道宅。
})()
}
Bue.prototype.init = 'wo'
var app = new Bue()
function Bue() {
console.log('this', this.init) //這里的this指向app。所以可以在Bue中直接使用Bue.prototype上的屬性
}
Bue.prototype.init = 'wo'
var app = new Bue() // new的時候會把Bue的上下文換成app實例的執(zhí)行一遍胸蛛。所以new Bue()時候可以執(zhí)行console.log
forEach 中的this
function hh () {
[].slice.call(node.childNodes).forEach(_compileNode, this); // 需要傳遞this
}
若想._compileNode函數(shù)中的this和函數(shù)hh的this指向一致污茵,就需要手動給forEach傳第二個參數(shù)this。