在简单的示例中理解this和setTimeout

时间:2016-09-15 13:02:29

标签: javascript

在下面的示例中,我有几个惊喜:

  

我很伤心,人们在投票之前甚至没有正确地阅读问题。 JSFiddle包装变量以将其设置为本地。请不要在这种情况下将其作为证明! ---而且,还有一个非常聪明的人删除了我的代码并将其包裹在小提琴中以显示他的愚蠢到了一个新的水平!

段:

this.a = 100;
var a = 200;

function b() {
  this.a = 300;
  setTimeout(function() {
    console.log(this.a)
  }, 0);
}
b();
console.log("Hello");
console.log(a);

结果:

enter image description here

查询:

  
      
  1. 当setTimeout为0时,第一个日志必须为300.为什么我之前看到Hello打印? (因为函数b在“console.log(Hello)”之前执行。

  2.   
  3. 第3个日志必须具有值“200”,因为两行中的this.a引用window.a,因为这指的是两个位置中的窗口对象。将一个仍为hods的值变为200.

  4.   
  5. 虽然chrome显示Hello,300,300 Fiddle显示Hello,200,300

  6.   

对这2个现象的任何解释?

  

注意:JSfiddle在函数中包装代码以将它们设置为局部变量,因此不要将其视为当前示例。试试Chrome!

2 个答案:

答案 0 :(得分:1)

如评论所述,

  

正在发生的事情是OP正在调用b()。这在内部调用setTimeout。在其中,OP更新this.a this指向窗口。因此300

以下是我在IIFE中包装代码的示例

(function() {
  this.a = 100;
  var a = 200;

  function b() {
    this.a = 300;
    setTimeout(function() {
      console.log(this.a)
    }, 0);
  }
  b();
  console.log("Hello");
  console.log(a);
})()

解释

// Here this points to window
this.a = 100;

// variables declared outside any functions are part of global scope (window)
var a = 200;

function b() {
  // this again points to window
  this.a = 300;
  setTimeout(function() {
    console.log(this.a)
  }, 0);
}
b();
console.log("Hello");
console.log(a);

答案 1 :(得分:1)

  

当setTimeout为0时,第一个日志必须为300.为什么我之前看到Hello打印? (因为函数b在" console.log(Hello)"。

之前执行

不,所有"超时"函数执行执行异步。当前代码段完成后,执行将插入下一个可用时间段 0只是很快安排它,它不会使它成为同步通话。

  

第3个日志必须具有值" 200",因为这两行中的this.a引用window.a,因为这指的是两个位置中的窗口对象。将一个仍为hods的值变为200。

这在很大程度上取决于this最初的含义。在初始thiswindow的普通Javascript环境中执行时,所有a引用相同的window.a,预期结果为300,因为这是它在第一次被记录之前所设定的。

  

虽然chrome显示Hello,300,300 Fiddle显示Hello,200,300

小提琴环境很特殊,初始this不是window