Javascript 中对象成员的创建和初始化顺序

Order of creation and initialization of object members in Javascript

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

那么,让我们举个简单的例子:

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

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

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

new Main();

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

  • 新的执行上下文已创建并添加到堆栈中
  • 扫描代码中的函数 [除非被调用,否则不会评估代码——它只是了解到那里有一个特定的函数]
  • 所有变量都挂了
  • this 变量正在赋值
  • 执行阶段开始:代码逐行执行(包括所有变量赋值等;如果调用任何函数,则会创建另一个执行上下文并重新开始该过程)

    在这个步骤列表中 this.method 的哪个位置创建和定义? 我四处寻找并发现在执行阶段,如果我在 this.method 实际定义之前调用它,则会抛出错误(这意味着实例方法尚不存在)。但是,如果我在实例方法内部调用代码后面定义的另一个实例方法,则一切正常: 函数主要(){ 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 的引用对象)?

    谢谢!

  • sayHello方法是一个函数的引用,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.sayHello2 方法之前尝试执行 this.sayHello(),您可以看到同样的事情。

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