手寫new

王振宇發表於2019-03-19
new運算子建立一個使用者定義的物件型別的例項或具有建構函式的內建物件的例項。

function Foo(name){
    this.name = name;
}
let foo = new Foo('小明');複製程式碼

當程式碼執行new Foo時,會發生以下事情:
1. 一個繼承自 Foo.prototype 的新物件被建立
2. 使用指定的引數呼叫建構函式 Foo,並將this繫結到新建立的物件
3. 由建構函式返回的物件就是new表示式的結果。如果建構函式沒有顯式返回一個物件,則使用步驟1建立的物件。(一般情況下,建構函式不返回值,但是使用者可以選擇主動返回物件,來覆蓋正常的物件建立步驟)

以上內容源自MDN

瞭解了new的原理,我們來自己動手實現一個:

function myNew(){
  // 建立一個新物件obj,宣告要返回的結果result,取引數的第一項為建構函式fn
  let obj = new Object(),result,fn = [].shift.call(arguments);
  // 將obj.__proto__連線到建構函式fn的原型
  obj.__proto__ = fn.prototype;
  // result接收建構函式執行後的返回結果
  result = arguments.length>0?fn.apply(obj,arguments):fn.apply(obj);
  // 如果建構函式返回一個物件,則將該物件返回,否則返回步驟1建立的物件
  return typeof result === 'object'?result:obj;
}
複製程式碼

如果有錯誤或者不嚴謹的地方,請給予指正,十分感謝!

相關文章