javascript 范围陷阱与 setTimeout 和绑定

pun*_*bit 3 javascript scope settimeout

对于下面的代码,我期待控制台 2 和 3 使用“Jupiter”,但是即使我传递了不同的上下文,也会将其绑定到全局窗口对象。

function otherScope () {
  this.sectionHeight = "Jupiter"
}

(function () {
    var sectionHeight = "Mars";
    (function () {
      setTimeout(function () {
        console.log('console 1', sectionHeight)
      })
    }())
}())

window.sectionHeight = "cool!";

(function () {
  setTimeout(function () {
    console.log('console 2', sectionHeight)
  })
}.bind(otherScope)())


setTimeout(function () {
  console.log('console 3', sectionHeight)
}.bind(otherScope))


setTimeout(function () {
  console.log('console 4', sectionHeight)
})
Run Code Online (Sandbox Code Playgroud)

Nie*_*els 5

otherScope 是一个函数,而不是一个具有属性的对象。你必须为此做一个new。所以:

var x = new otherScope();
x.sectionHeight;
Run Code Online (Sandbox Code Playgroud)

接下来,this 的作用域只达到当前作用域。setTimeout 创建一个新的作用域。因此我们需要再做一次绑定。或者在 setTimeout 之外的第一个范围内创建一个变量。

一些示例(范围内的变量):

(function () {
  var theScope = this;
  setTimeout(function () {
    console.log('console 2', theScope.sectionHeight)
  });
}.bind(new otherScope())())
Run Code Online (Sandbox Code Playgroud)

一些例子(另一个绑定):

(function () {
  setTimeout(function () {
    console.log('console 2', this.sectionHeight)
  }.bind(this)); // Pass the context to the new scope
}.bind(new otherScope())())
Run Code Online (Sandbox Code Playgroud)