[英]ES6 Arrow functions vs ES5: how to know which function to bind `this` to when using ES5 non-arrow function
[英]Scope of arrow function vs es5 function in setTimeout
我正在試驗這個和箭頭函數。 關於 setTimeout 中箭頭函數的詞法范圍遇到了一些麻煩。
makeSound 方法將 this 作為狗對象返回。 既然箭頭函數在 setTimeout 方法里面,為什么不取全局對象的作用域呢? 有趣的是,whatIsThis 方法返回的是 Timeout 對象而不是全局對象。 我對此也很困惑。
const dog = { name: 'fluffy', type: 'dog', sound: 'woof!', makeSound: function() { setTimeout(() => { console.log("makeSound", this) }, 1000) }, whatIsThis: function() { setTimeout(function() { console.log("whatisthis", this) }, 1000) } } dog.makeSound() // returns dog obj dog.whatIsThis() // returns Timeout obj setTimeout(() => { console.log("global", this) }, 1000) // returns global obj
為什么因為箭頭函數位於setTimeout方法內部,所以它不采用全局對象的范圍?
回調不在setTimeout
函數內部。 它作為參數傳遞給 setTimeout
函數。
考慮以下等效代碼:
const dog = {
name: 'fluffy',
type: 'dog',
sound: 'woof!',
makeSound: function() {
const cb = () => console.log("makeSound", this);
setTimeout(cb, 1000)
},
}
此代碼的行為完全相同。 唯一的區別是,回調函數在傳遞給setTimeout
之前先分配給變量。
這應該表明箭頭功能不是在setTimeout
內部,而是在makeSound
內部。 箭頭函數像其他變量一樣,按詞法解析this
。 所以我們要找出什么價值this
里面makeSound
是。 為了找出答案,我們必須研究如何調用該方法。 由於它被稱為dog.makeSound()
, this
它是指dog
。
箭頭函數所聲明的作用域是包圍它的函數的范圍( dog.makeSound
),而不是箭頭函數所傳遞給的函數的范圍。
WHE你打電話dog.makeSound()
this
在內部makeSound
功能是指dog
,因此箭頭函數中這樣做了。
// no matter what the surrounding is ...
const that = this;
/*no matter whats here*/(() => {
console.log(that === this); // this will always be true
})();
有趣的是,whatIsThis方法返回Timeout對象,而不是全局對象。 我對此也感到困惑。
我也是。 這種行為很奇怪,您確定您不會誤解控制台輸出嗎?
實際上不是它不能訪問全局變量,而是問題在於setTimeout具有它自己的作用域,因此它只是克服了全局變量。
您可以做的是:
let self = this;
const dog = {
name: 'fluffy',
type: 'dog',
sound: 'woof!',
makeSound: function() {
setTimeout(() => {
console.log("makeSound", self )
}, 1000)
},
whatIsThis: function() {
setTimeout(function() {
console.log("whatisthis", this)
}, 1000)
}
}
dog.makeSound() // returns dog obj
dog.whatIsThis() // returns Timeout obj
setTimeout(()=>{
console.log("global", this)
}, 1000);
我希望這能解決您的全球范圍問題。希望對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.