繁体   English   中英

setTimeout 中箭头函数与 es5 函数的范围

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM