此頁面由社群從英文翻譯而來。了解更多並加入 MDN Web Docs 社群。
Object.create()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
Object.create() 指定其原型物件與屬性,創建一個新物件。
In this article
語法
Object.create(proto[, propertiesObject])參數
proto指定新物件的原型 (prototype) 物件。
propertiesObject選用,為一物件。如有指定且非
undefined,則此參數物件中可列舉出的屬性 (即參數物件自身定義的屬性,並非指原型鏈上的enumerable特性 ) 對應其屬性名稱,根據其屬性敘述元 (property descriptors) 加進新創建的物件。這些屬性對應到Object.defineProperties()的第二個參數。
回傳
具有指定原型物件與屬性的新物件。
例外
範例
>使用Object.create() 實現類別繼承
下方是如何使用Object.create() 去實現類別繼承的示範,此為 JavaScript 支援的單一繼承.。
// Shape - 父類別function Shape() { this.x = 0; this.y = 0;}// 父類別的方法Shape.prototype.move = function (x, y) { this.x += x; this.y += y; console.info("Shape moved.");};// Rectangle - 子類別function Rectangle() { Shape.call(this); // call super constructor.}// 子類別擴展(extends)父類別Rectangle.prototype = Object.create(Shape.prototype);Rectangle.prototype.constructor = Rectangle;var rect = new Rectangle();console.log("Is rect an instance of Rectangle?", rect instanceof Rectangle); // trueconsole.log("Is rect an instance of Shape?", rect instanceof Shape); // truerect.move(1, 1); // Outputs, 'Shape moved.'也可像 mixin 繼承多個物件。
function MyClass() { SuperClass.call(this); OtherSuperClass.call(this);}// 繼承一個父類別MyClass.prototype = Object.create(SuperClass.prototype);// mixin另一個父類別Object.assign(MyClass.prototype, OtherSuperClass.prototype);// 重新指定建構式MyClass.prototype.constructor = MyClass;MyClass.prototype.myMethod = function () { // do a thing};Object.assign 複製 OtherSuperClass 原型上的所有屬性到 MyClass 的原型上,使所有 MyClass 的實例都能使用。Object.assign 為 ES2015 標準且有 polyfill。如需支援較舊的瀏覽器,可使用第三方套件實現如jQuery.extend() 或.assign() 。
propertiesObject 參數的使用
var o;// 建立以null為原型的物件o = Object.create(null);o = {};// 等同於:o = Object.create(Object.prototype);// Example where we create an object with a couple of sample properties.// (Note that the second parameter maps keys to *property descriptors*.)o = Object.create(Object.prototype, { // foo 為數值屬性 foo: { writable: true, configurable: true, value: "hello" }, // bar 為 getter-and-setter 訪問屬性 bar: { configurable: false, get: function () { return 10; }, set: function (value) { console.log("Setting `o.bar` to", value); }, /* with ES5 Accessors our code can look like this get function() { return 10; }, set function(value) { console.log('setting `o.bar` to', value); } */ },});function Constructor() {}o = new Constructor();// 等同於:o = Object.create(Constructor.prototype);// Of course, if there is actual initialization code in the// Constructor function, the Object.create() cannot reflect it// 創建一個新物件,指定原型是全新的空物件,並加入值為 42 的屬性'p'o = Object.create({}, { p: { value: 42 } });// 屬性敘述元 writable, enumerable , configurable 未定義,預設皆為 falseo.p = 24;o.p;// 42o.q = 12;for (var prop in o) { console.log(prop);}// 'q'delete o.p;// false// to specify an ES3 propertyo2 = Object.create( {}, { p: { value: 42, writable: true, enumerable: true, configurable: true, }, },);Polyfill
此 polyfill 涵蓋了主要的使用情境:指定一個原型創建一個新的物件,第二個參數為選用。
要注意的是在 ES5 的Object.create 中,[[Prototype]] 可以為null,但在 ECMAScript 5 以前的版本,polyfill 會因為繼承限制(limitation inherent)而不支援此情形。
if (typeof Object.create !== "function") { Object.create = function (proto, propertiesObject) { if ( !( proto === null || typeof proto === "object" || typeof proto === "function" ) ) { throw TypeError("Argument must be an object, or null"); } var temp = new Object(); temp.__proto__ = proto; if (typeof propertiesObject === "object") Object.defineProperties(temp, propertiesObject); return temp; };}規範
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-object.create> |