我正在试验这个和箭头函数。 在 setTimeout 中箭头函数的词法范围方面遇到了一些麻烦。
方法将此作为狗对象返回。为什么它不占用全局对象的作用域,因为箭头函数在 setTimeout 方法内?有趣的是,whatIsThis 方法返回超时对象而不是全局对象。我也对此感到困惑。
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
,就像任何其他变量一样。因此,我们必须找出makeSound
内部this
的价值是什么。为了找出答案,我们必须看看该方法是如何调用的。由于它被称为dog.makeSound()
,this
指的是dog
。
箭头函数声明的作用域是围绕它的函数的作用域(dog.makeSound
(,而不是箭头函数传递到的函数。
不管你怎么称呼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 方法返回超时对象而不是全局对象。我也对此感到困惑。
我也是。这种行为很奇怪,您确定您没有误解控制台输出吗?