js中的new()到底做了些什麼?

李老六發表於2018-03-26

要建立 Person 的新例項,必須使用 new 操作符。以這種方式呼叫建構函式實際上會經歷以下 4
個步驟:
(1) 建立一個新物件;
(2) 將建構函式的作用域賦給新物件(因此 this 就指向了這個新物件) ;
(3) 執行建構函式中的程式碼(為這個新物件新增屬性) ;
(4) 返回新物件。

new 操作符

在有上面的基礎概念的介紹之後,在加上new操作符,我們就能完成傳統物件導向的class + new的方式建立物件,在JavaScript中,我們將這類方式成為Pseudoclassical。
基於上面的例子,我們執行如下程式碼

var obj = new Base();

這樣程式碼的結果是什麼,我們在Javascript引擎中看到的物件模型是:

new操作符具體幹了什麼呢?其實很簡單,就幹了三件事情。

var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

第一行,我們建立了一個空物件obj
第二行,我們將這個空物件的__proto__成員指向了Base函式物件prototype成員物件
第三行,我們將Base函式物件的this指標替換成obj,然後再呼叫Base函式,於是我們就給obj物件賦值了一個id成員變數,這個成員變數的值是”base”,關於call函式的用法。


如果我們給Base.prototype的物件新增一些函式會有什麼效果呢?
例如程式碼如下:

Base.prototype.toString = function() {
return this.id;
}

那麼當我們使用new建立一個新物件的時候,根據__proto__的特性,toString這個方法也可以做新物件的方法被訪問到。於是我們看到了:
構造子中,我們來設定‘類’的成員變數(例如:例子中的id),構造子物件prototype中我們來設定‘類’的公共方法。於是通過函式物件和Javascript特有的__proto__與prototype成員及new操作符,模擬出類和類例項化的效果。

注:本文為轉載文章[文章連結]


相關文章