目錄
- 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來創建實體
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/347027.html
標籤:JavaScript
