Object.create()
**Object.create()
** 静态方法创建一个新对象,使用现有对象作为新创建对象的原型。
试一试
语法
Object.create(proto)
Object.create(proto, propertiesObject)
参数
proto
-
应作为新创建对象原型的对象。
propertiesObject
可选-
如果指定且不为
undefined
,则其 可枚举自身属性 指定要添加到新创建对象的属性描述符,以及相应的属性名称。这些属性对应于Object.defineProperties()
的第二个参数。
返回值
具有指定原型对象和属性的新对象。
异常
示例
使用 Object.create() 实现经典继承
以下是如何使用 Object.create()
实现经典继承的示例。这适用于单一继承,这是 JavaScript 支持的全部继承方式。
// 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()
,我们可以创建具有指定原型和一些属性的对象。请注意,第二个参数将键映射到属性描述符——这意味着您还可以控制每个属性的可枚举性、可配置性等,而这在对象初始化器中是无法做到的。
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__
键。
o = Object.create(null);
// Is equivalent to:
o = { __proto__: null };
默认情况下,属性不可写、不可枚举且不可配置。
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
要指定与初始化器中属性具有相同属性的属性,请显式指定 writable
、enumerable
和 configurable
。
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
运算符的行为。
function Constructor() {}
o = new Constructor();
// Is equivalent to:
o = Object.create(Constructor.prototype);
当然,如果 Constructor
函数中存在实际的初始化代码,则 Object.create()
方法无法反映它。
规范
规范 |
---|
ECMAScript 语言规范 # sec-object.create |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。