Object.create()
從 ECMAScript 5.1 就開始提供,與 new
不同的是 Object.create()
讓我們可直接根據 Prototype 建立 Object,事實上我們也可土炮實作。
Version
ECMAScript 2015
Object.create()
let _book = {
showDescription: function() {
return `${this.title} / ${this.price}`
}
}
let book = Object.create(_book)
book.title = 'FP in JavaScript'
book.price = 100
book.showDescription() // ?
為了節省記憶體,我們會將 Object 的 method 建立在其 prototype。
因此可先將 showDescription()
建立在 _book
,以此為 prototype 透過 Object.create()
建立之。
Constructor Function
Object.create_ = function(prototype) {
let F = function() {}
F.prototype = prototype
return new F()
}
let _book = {
showDescription: function() {
return `${this.title} / ${this.price}`
}
}
let book = Object.create_(_book)
book.title = 'FP in JavaScript'
book.price = 100
book.showDescription() // ?
事實上我們也可以土炮建立 Object.create()
。
我們知道 constructor function 的 prototype
property 在經過 new
之後,會將其記憶體位址複製給 object 的 __proto__
property,因此我們可透過 constructor function 實作 Object.create()
。
第 1 行
Object.create_ = function(prototype) {
let F = function() {}
F.prototype = prototype
return new F()
}
自行建立 Object.create_()
模擬 Object.create()
。
先動態建立 F()
constructor function,再將傳入的 prototype
Object 指定給 F()
的 prototype
property,如此透過 new
所建立的 Object 其 prototype 就是 prototype
Object。
Proto Property
Object.create_ = function(prototype) {
let obj = {}
obj.__proto__ = prototype
return obj
}
let _book = {
showDescription: function() {
return `${this.title} / ${this.price}`
}
}
let book = Object.create_(_book)
book.title = 'FP in JavaScript'
book.price = 100
book.showDescription() // ?
第 1 行
Object.create_ = function(prototype) {
let obj = {}
obj.__proto__ = prototype
return obj
}
Constructor function 說穿了只是透過 new
幫我們指定到 object 的 __proto__
property,既然如此,我們也可自行將 prototype
object 指定給 __proto__
property。
Object.setPrototypeOf()
Object.create_ = prototype => Object.setPrototypeOf({}, prototype)
let _book = {
showDescription: function() {
return `${this.title} / ${this.price}`
}
}
let book = Object.create_(_book)
book.title = 'FP in JavaScript'
book.price = 100
book.showDescription() // ?
第 1 行
Object.create_ = prototype => Object.setPrototypeOf({}, prototype)
也可使用 Object.setPropertyOf()
直接指定 prototype,只要一行即可。
Conclusion
- 實務上雖然直接使用
Object.create()
即可,但藉由自行實作Object.create()
可更了解 ECMAScript 的 prototype 機制
Reference
MDN, Object.create()
MDN, Object.setPrototypeOf()
MDN, Object.prototype.proto
許國政, 008 天重新認識 JavaScript