Object.create()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

Object.create() 靜態方法建立一個新物件,使用現有物件作為新建立物件的原型。

試一試

const person = {
  isHuman: false,
  printIntroduction() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  },
};

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // Inherited properties can be overwritten

me.printIntroduction();
// Expected output: "My name is Matthew. Am I human? true"

語法

js
Object.create(proto)
Object.create(proto, propertiesObject)

引數

proto

應成為新建立物件的原型的物件。

propertiesObject 可選

如果指定且不為 undefined,則為一個物件,其 可列舉的自有屬性 指定屬性描述符,這些描述符將被新增到新建立的物件中,屬性名與描述符對應。這些屬性對應於 Object.defineProperties() 的第二個引數。

返回值

一個具有指定原型物件和屬性的新物件。

異常

TypeError

如果 proto 既不是 null 也不是 Object,則丟擲此錯誤。

示例

使用 Object.create() 進行類式繼承

下面是一個如何使用 Object.create() 實現類式繼承的示例。這是單繼承,也是 JavaScript 所支援的。

js
// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function (x, y) {
  this.x += x;
  this.y += y;
  console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype, {
  // If you don't set Rectangle.prototype.constructor to Rectangle,
  // it will take the prototype.constructor of Shape (parent).
  // To avoid that, we set the prototype.constructor to Rectangle (child).
  constructor: {
    value: Rectangle,
    enumerable: false,
    writable: true,
    configurable: true,
  },
});

const rect = new Rectangle();

console.log("Is rect an instance of Rectangle?", rect instanceof Rectangle); // true
console.log("Is rect an instance of Shape?", rect instanceof Shape); // true
rect.move(1, 1); // Logs 'Shape moved.'

請注意,使用 create() 時需要注意一些細節,例如重新新增 constructor 屬性以確保語義正確。雖然 Object.create() 被認為比使用 Object.setPrototypeOf() 修改原型效能更好,但如果在例項尚未建立且屬性訪問尚未最佳化的情況下,這種差異實際上是微不足道的。在現代程式碼中,無論如何都應優先使用 class 語法。

使用 Object.create() 的 propertiesObject 引數

Object.create() 允許對物件建立過程進行精細控制。實際上,物件字面量語法Object.create() 的語法糖。透過 Object.create(),我們可以建立具有指定原型和某些屬性的物件。請注意,第二個引數將鍵對映到屬性描述符 — 這意味著您還可以控制每個屬性的可列舉性、可配置性等,而這是您在物件字面量中無法做到的。

js
o = {};
// Is equivalent to:
o = Object.create(Object.prototype);

o = Object.create(Object.prototype, {
  // foo is a regular data property
  foo: {
    writable: true,
    configurable: true,
    value: "hello",
  },
  // bar is an accessor property
  bar: {
    configurable: false,
    get() {
      return 10;
    },
    set(value) {
      console.log("Setting `o.bar` to", value);
    },
  },
});

// Create a new object whose prototype is a new, empty
// object and add a single property 'p', with value 42.
o = Object.create({}, { p: { value: 42 } });

使用 Object.create(),我們可以建立一個原型為 null 的物件。在物件字面量中,等效的語法是 __proto__ 鍵。

js
o = Object.create(null);
// Is equivalent to:
o = { __proto__: null };

預設情況下,屬性不是可寫、可列舉或可配置的。

js
o.p = 24; // throws in strict mode
o.p; // 42

o.q = 12;
for (const prop in o) {
  console.log(prop);
}
// 'q'

delete o.p;
// false; throws in strict mode

要指定一個與字面量中具有相同屬性的屬性,請顯式指定 writableenumerableconfigurable

js
o2 = Object.create(
  {},
  {
    p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true,
    },
  },
);
// This is not equivalent to:
// o2 = Object.create({ p: 42 })
// which will create an object with prototype { p: 42 }

您可以使用 Object.create() 來模仿 new 運算子的行為。

js
function Constructor() {}
o = new Constructor();
// Is equivalent to:
o = Object.create(Constructor.prototype);

當然,如果 Constructor 函式中有實際的初始化程式碼,Object.create() 方法無法反映它。

規範

規範
ECMAScript® 2026 語言規範
# sec-object.create

瀏覽器相容性

另見