JavaScript:模擬實現new

模擬實現new

首先我們要知道new做了什麼

  1. 創建一個新對象,並繼承其構造函數的prototype,這一步是爲了繼承構造函數原型上的屬性和方法
  2. 執行構造函數,方法內的this被指定爲該新實例,這一步是爲了執行構造函數內的賦值操作
  3. 返回新實例(規範規定,如果構造方法返回了一個對象,那麼返回該對象,否則返回第一步創建的新對象)
// new是關鍵字,這裏我們用函數來模擬,new Foo(args) <=> myNew(Foo, args)
function myNew(foo, ...args) {
  // 創建新對象,並繼承構造方法的prototype屬性, 這一步是爲了把obj掛原型鏈上, 相當於obj.__proto__ = Foo.prototype
  let obj = Object.create(foo.prototype)  
  
  // 執行構造方法, 併爲其綁定新this, 這一步是爲了讓構造方法能進行this.name = name之類的操作, args是構造方法的入參, 因爲這裏用myNew模擬, 所以入參從myNew傳入
  let result = foo.apply(obj, args)

  // 如果構造方法已經return了一個對象,那麼就返回該對象,否則返回myNew創建的新對象(一般情況下,構造方法不會返回新實例,但使用者可以選擇返回新實例來覆蓋new創建的對象)
  return Object.prototype.toString.call(result) === '[object Object]' ? result : obj
}

// 測試:
function Foo(name) {
  this.name = name
}
const newObj = myNew(Foo, 'zhangsan')
console.log(newObj)                 // Foo {name: "zhangsan"}
console.log(newObj instanceof Foo)  // true

Object.create()方法創建一個新對象,並使用現有的對象來提供新創建的對象的__proto__。

參考文檔:2萬字 | 前端基礎拾遺90問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章