前端面試手寫程式碼——模擬實現new運算子
阿新 • • 發佈:2021-10-21
1 new 運算子簡介
2 new 究竟幹了什麼事
3 模擬實現 new 運算子
4 補充
目錄
運算子就幹了這麼
⚠ 預備知識:
- 瞭解原型和原型鏈
- 瞭解
this
繫結
1 new 運算子簡介
MDN文件:
new
運算子建立一個使用者定義的物件型別的例項或具有建構函式的內建物件的例項。
class Person {
constructor(name) {
this.name = name;
}
}
// 建立自定義物件型別的例項
const person = new Person('小明')
// 建立具有建構函式的內建物件的例項
const date = new Date()
new
的作用:建立物件的例項
2 new 究竟幹了什麼事
上面說了new
的作用是建立物件的例項,那麼它究竟是怎麼建立例項的,內部幹了哪幾件事?
以new Person()
為例,當它執行時,會發生以下事情:
-
建立一個空的簡單
JS
物件const obj = {}
-
給這個物件新增屬性
__proto__
,並將該屬性連結到建構函式的原型物件obj.__proto__ = Person.prototype
-
呼叫建構函式
Person
,並將this
繫結到新建立的物件obj
Person.apply(obj)
-
如果建構函式沒有顯式返回一個物件,則返回新建立的物件,即
obj
3 模擬實現 new 運算子
如上所述,new
4
件事,下面我們就根據這4個步驟用函式來模擬實現new
(面試手寫程式碼)
const _new = function(constructor, ...args) {
const obj = {}
obj.__proto__ = constructor.prototype
const res = constructor.apply(obj, args)
// 這一步在"補充"中會詳細解釋
return res instanceof Object ? res : obj
}
程式碼非常簡單,就是按照上面4
步,一步一步寫就可以了
4 補充
-
ES5
Object.create
方法,該方法可以建立一個物件,並讓新物件的__proto__
屬性指向已經存在的物件。所以我們可以使用這個方法合併1、2兩步
const obj = Object.create(constructor.prototype) // 等價於 const obj = {} obj.__proto__ = constructor.prototype
-
對於第
4
步,再解釋一下-
如果建構函式沒有顯式
return
(通常情況)那麼
person
就是新建立的物件obj
-
如果建構函式返回的不是一個物件,比如
1
、"abc"
那麼
person
還是新建立的物件obj
function Person() { ... return 1 }
-
如果建構函式顯式返回了一個物件,比如
{}
、function() {}
那麼
person
就不是新建立的物件obj
了,而是顯式return
的這個物件function Person() { // 函式也是物件 return function() {} }
所以我們在
_new
函式最後一句程式碼是:return res instanceof Object ? res : obj
-
-
注意,模擬實現的函式
_new
傳入的引數只能是建構函式,不能是類class Animal { ...}_new(Animal)// 會報錯:Class constructor Animal cannot be invoked without 'new'// 類只能通過new來建立例項
公眾號【前端嘛】獲取更多優質內容