[英]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.