1

我对 JS 对象中成员的初始化顺序和创建顺序有一些疑问。
据我了解,当调用任何函数时,都会创建一个函数执行上下文。在这些函数中处理代码还有两个阶段:创建和执行。

所以,让我们举个简单的例子:

function Main() {
  var a = "1";

  this.sayHello = function() {
     console.log("Hello!");
  }

  function inner() {
     var b = 2;
  }
}

new Main();

创建和初始化所有成员的顺序是什么?我知道当我们不使用对象时它是如何工作的:

  • 创建新的执行上下文并将其添加到堆栈中
  • 扫描代码以查找函数[除非调用代码,否则不会评估代码——它只是知道那里有一个特定的函数]
  • 所有变量都被提升
  • 这个变量被赋值
  • 执行阶段开始:代码逐行执行(包括所有变量赋值等;如果调用任何函数,则创建另一个执行上下文并重新开始流程)

    在这个步骤列表中,this.method是在哪里创建和定义的?我四处寻找并发现在执行阶段,如果我在this.method实际定义之前调用它,则会引发错误(意味着该实例方法尚不存在)。但是,如果我在实例方法内部调用稍后在代码中定义的另一个实例方法,则一切正常: function Main() { var a = "1";

      // this.sayHello() -- error!!
    
      this.sayHello = function() {
         this.sayHello2(); // no error (???)
         console.log("Hello!");
      }
    
      this.sayHello2 = function() {
         console.log("Hello2!");
      }
    
      function inner() {
         var b = 2;
      }
    }
    
    new Main();
    

    任何人都可以帮助我了解何时创建实例方法以及何时定义它们?JS 中的原型对象如何使执行上下文不同(除了更改this的引用对象)?

    谢谢!

  • 4

    1 回答 1

    0

    sayHellomethod 是对函数的引用,该函数this.sayHello将在稍后执行,sayHello2方法将被初始化。如果你做这样的事情:

      this.sayHello = (function() {
         this.sayHello2(); //error
         console.log("Hello!");
      }).call(this);
    
      this.sayHello2 = function() {
         console.log("Hello2!");
      }
    
      function inner() {
         var b = 2;
      }
    }
    
    new Main();
    

    使用 iife,因此该函数将立即调用,而不是抛出错误,因为 js 不知道this.sayHello2. this.sayHello()如果在定义方法之前尝试执行,您可以看到同样的事情this.sayHello2

    Js解释器没有简单地到达sayHello函数中的代码,所以没有错误

    于 2015-11-14T00:06:49.353 回答