深刻一點 - 用 new 的時候到底發生了什麼?

來自: https://zswfx.com/articles/5db9285f9cf7c10e840e5c6a

咱們常常用new來建立一個對象,可是建立對象過程當中,到底發生了什麼呢?git

new 操做符的過程


上面是mdn的定義。github

經過上面定義,咱們知道使用new的時候,JS引擎就會給咱們建立一個空對象做爲 this值,而後執行函數,若函數沒有返回值,則默認返回這個空對象app

模擬 new 函數來建立對象。

根據上面mdn定義new過程,咱們來模擬一下new的過程,只有模擬後,咱們就知道使用new後,引擎是如何操做的,咦下面例子爲例:函數

function Person(name, age) {
    this.name = name;
    this.age = age;  
}

很簡單一個例子,建立一我的。this

建立一個空對象並連接到傳入對象中

function mockNew(...args) {
  const Constructor = args[0];
  const object = Object.create(Constructor.prototype);
}

在這裏,經過 Object.create 建立新對象,並把新對象 __proto__ 指向傳入對象的 prototype.spa

Object.create 查看這裏

把新對象做爲上下文注入

function mockNew(...args) {
  const Constructor = args[0];
  const object = Object.create(Constructor.prototype);
  const params = args.slice(1);
  Constructor.apply(object, params);
}

經過 apply 函數,將object當成 this傳入。prototype

返回判斷

function mockNew(...args) {
  const Constructor = args[0];
  const object = Object.create(Constructor.prototype);
  const params = args.slice(1);
  const ret = Constructor.apply(object, params);
  return ret || object;
}

判斷結果,並返回。code

跑一下例子

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const pe = mockNew(Person, '戰三', 23)
console.log(pe);

經過對比,發現一抹同樣。咱們就模擬的整個new 的過程。對象

規範上過程

es有規範,規範位於 11.2.2 new 運算符new 屬於左值表達式(表明數值位於=號的左側)
blog

這是在規範過程,在規範中分爲兩個狀況,有參數狀況和無參數狀況,空參數狀況按照NewExpression: new NewExpression的左值表達式方式執行,執行的事函數無參數狀況,有參數則是按照 MemberExpression: new MemberExpression Arguments 方式執行,都有關於異常處理狀況,不一樣的是第二種會去獲取函數參數列表,並傳入[[Construct]] 內。

NewExpression: new NewExpressionMemberExpression: new MemberExpression Arguments 均是左值表達式

總結

直接用mdn上的描述吧:

建立一個對象類型,須要建立一個指定其名稱和屬性的函數;對象的屬性能夠指向其餘對象,看下面的例子:

當代碼 new Foo(...) 執行時,會發生如下事情:

  1. 一個繼承自 Foo.prototype 的新對象被建立。
  2. 使用指定的參數調用構造函數 Foo,並將 this 綁定到新建立的對象。new Foo 等同於 new Foo(),也就是沒有指定參數列表,Foo 不帶任何參數調用的狀況。
  3. 由構造函數返回的對象就是 new 表達式的結果。若是構造函數沒有顯式返回一個對象,則使用步驟1建立的對象。(通常狀況下,構造函數不返回值,可是用戶能夠選擇主動返回對象,來覆蓋正常的對象建立步驟)

源碼地址: https://github.com/zsirfs/con...

相關文章
相關標籤/搜索