簡體   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