此页面由社区从英文翻译而来。了解更多并加入 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
尝试一下
const person = { isHuman: false, printIntroduction: function () { 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 overwrittenme.printIntroduction();// Expected output: "My name is Matthew. Am I human? true"语法
Object.create(proto)Object.create(proto, propertiesObject)参数
proto新创建对象的原型对象。
propertiesObject可选如果该参数被指定且不为
undefined,则该传入对象可枚举的自有属性将为新创建的对象添加具有对应属性名称的属性描述符。这些属性对应于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); // 调用父类构造函数。}// 子类继承父类Rectangle.prototype = Object.create(Shape.prototype, { // 如果不将 Rectangle.prototype.constructor 设置为 Rectangle, // 它将采用 Shape(父类)的 prototype.constructor。 // 为避免这种情况,我们将 prototype.constructor 设置为 Rectangle(子类)。 constructor: { value: Rectangle, enumerable: false, writable: true, configurable: true, },});const rect = new Rectangle();console.log("rect 是 Rectangle 类的实例吗?", rect instanceof Rectangle); // trueconsole.log("rect 是 Shape 类的实例吗?", rect instanceof Shape); // truerect.move(1, 1); // 打印 'Shape moved.'需要注意的是,使用create() 也有一些要注意的地方,比如重新添加constructor 属性以确保正确的语义。虽然Object.create() 被认为比使用Object.setPrototypeOf() 修改原型更具有性能优势,但如果没有创建实例并且属性访问还没有被优化,它们之间的差异实际上是可以忽略不计的。在现代代码中,无论如何都应该优先使用类语法。
使用 Object.create() 的 propertyObject 参数
Object.create() 方法允许对对象创建过程进行精细的控制。实际上,字面量初始化对象语法是Object.create() 的一种语法糖。使用Object.create(),我们可以创建具有指定原型和某些属性的对象。请注意,第二个参数将键映射到属性描述符,这意味着你还可以控制每个属性的可枚举性、可配置性等,而这在字面量初始化对象语法中是做不到的。
o = {};// 等价于:o = Object.create(Object.prototype);o = Object.create(Object.prototype, { // foo 是一个常规数据属性 foo: { writable: true, configurable: true, value: "hello", }, // bar 是一个访问器属性 bar: { configurable: false, get() { return 10; }, set(value) { console.log("Setting `o.bar` to", value); }, },});// 创建一个新对象,它的原型是一个新的空对象,并添加一个名为 'p',值为 42 的属性。o = Object.create({}, { p: { value: 42 } });使用Object.create(),我们可以创建一个原型为null 的对象。在字面量初始化对象语法中,相当于使用__proto__ 键。
o = Object.create(null);// 等价于:o = { __proto__: null };默认情况下,属性是不可写、可枚举和可配置的。
o.p = 24; // 在严格模式下会报错o.p; // 42o.q = 12;for (const prop in o) { console.log(prop);}// 'q'delete o.p;// false;在严格模式下会报错如果要指定与字面量对象中相同的属性,请显式指定writable、enumerable 和configurable。
o2 = Object.create( {}, { p: { value: 42, writable: true, enumerable: true, configurable: true, }, },);// 这与以下语句不等价:// o2 = Object.create({ p: 42 })// 后者将创建一个原型为 { p: 42 } 的对象。你可以使用Object.create() 来模仿new 运算符的行为。
function Constructor() {}o = new Constructor();// 等价于:o = Object.create(Constructor.prototype);当然,如果Constructor 函数中有实际的初始化代码,那么Object.create() 方法就无法反映它。
规范
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-object.create> |