我正在尝试使用此功能和箭头功能。 在setTimeout中遇到箭头函数的词法范围方面的麻烦。
makeSound方法将其作为dog对象返回。为什么因为箭头函数位于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
答案 0 :(得分:0)
为什么箭头功能位于setTimeout方法内部,为什么它不占用全局对象的范围?
回调不在setTimeout
函数的内部。它作为参数{em>传递给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
。
答案 1 :(得分:-1)
箭头函数所声明的作用域是包围它的函数 (dog.makeSound
)的作用域,而不是箭头函数所传递给的函数。
在调用dog.makeSound()
内的this
时,makeSound
指的是dog
,因此在arrow函数内也是如此。
// no matter what the surrounding is ...
const that = this;
/*no matter whats here*/(() => {
console.log(that === this); // this will always be true
})();
有趣的是,whatIsThis方法返回Timeout对象,而不是全局对象。我对此也感到困惑。
我也是。这种行为很奇怪,您确定您不会误解控制台输出吗?
答案 2 :(得分:-2)
实际上不是不是它无法访问全局变量,而是问题在于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);
我希望这能解决您的全球范围问题。希望对您有所帮助。