JavaScript - 为什么此代码记录为“未定义”但显示在Chrome控制台中? (封闭件)

时间:2014-01-06 11:39:32

标签: javascript closures

我做了这个例子:

(function(_stack_){
  var stack = {
    over: 'flow',
    run: function(){
      console.log(this);
    }
  };
  _stack_.app = stack;
  stack.run();
})(this);

app.foo = 'bar';

Chrome控制台中的输出:

enter image description here

但是如何输出:

(function(_stack_){
  var stack = {
    over: 'flow',
    run: function(){
      console.log(this.foo); // undefined
    }
  };
  _stack_.app = stack;
  stack.run();
})(this);

app.foo = 'bar';

等于undefined,而它显示在Chrome控制台中?

查看 JS Bin

编辑: 我知道它变得未定义,因为stack.run()在分配app.foo之前被调用。问题是它是如何出现在控制台中的?

2 个答案:

答案 0 :(得分:2)

this.foo在你运行它时不可用

这是糟糕的设计,当使用这样的javascript时,你可能更多地使用自定义构造函数和事件处理。您的代码和问题表明应在更新动态创建的变量app时执行run方法。除非你为此实现一些事件处理,否则这种情况永远不会发生。

如果在设置app.foo变量后调用app.run();,则代码可以正常工作。

// Antipattern ahead!
(function(_stack_){
  var stack = {
    over: 'flow',
    run: function(){
      // Prevent error messages
      if(typeof this.foo === 'undefined') {
          return;
      }
      console.log("log: " + this.foo); // undefined
    }
  };
  _stack_.app = stack;
})(this);

app.foo = 'bar';
app.run(); // log: bar

答案 1 :(得分:1)

原因是因为stack.run()是在app对象上创建foo属性之前执行的。

当您查看调试器时,已创建foo属性。