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