Object.create
Object.create
Object.create()
方法会使用指定的原型对象及其属性去创建一个新的对象。
语法
Object.create(proto[, propertiesObject])
参数
proto
新创建对象的原型对象。
返回值
在指定原型对象上添加新属性后的对象。
异常
如果proto
参数不是 null
或一个对象,则抛出一个TypeError
异常。
例子
用 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
Rectangle.prototype.constructor = Rectangle;
var 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 // Outputs, 'Shape moved.'
如果你希望能继承到多个对象,则可以使用混入的方式。
function MyClass() {
SuperClass.call(this
OtherSuperClass.call(this
}
// inherit one class
MyClass.prototype = Object.create(SuperClass.prototype
// mixin another
Object.assign(MyClass.prototype, OtherSuperClass.prototype
// re-assign constructor
MyClass.prototype.constructor = MyClass;
MyClass.prototype.myMethod = function() {
// do a thing
};
Object.assign 会把 OtherSuperClass
原型上的函数拷贝到MyClass
原型上,使 MyClass
的所有实例都可用 OtherSuperClass
的方法。Object.assign 是在 ES2015 引入的,且可用 polyfilled。要支持旧浏览器的话,可用使用 jQuery.extend() 或者 _.assign()。
使用 Object.create 的 propertyObject参数
var o;
// create an object with null as prototype
o = Object.create(null
o = {};
// is equivalent to:
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 is a regular 'value property'
foo: {
writable: true,
configurable: true,
value: 'hello'
},
// bar is a getter-and-setter (accessor) property
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(
// is equivalent to:
o = Object.create(Constructor.prototype
// Of course, if there is actual initialization code
// in the Constructor function,
// the Object.create() cannot reflect it
// 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 } }
// by default properties ARE NOT writable,
// enumerable or configurable:
o.p = 24;
o.p;
// 42
o.q = 12;
for (var prop in o) {
console.log(prop
}
// 'q'
delete o.p;
// false
// to specify an ES3 property
o2 = Object.create{}, {
p: {
value: 42,
writable: true,
enumerable: true,
configurable: true
}
}
Polyfill
这个 polyfill 涵盖了主要的应用场景,它创建一个已经选择了原型的新对象,但没有把第二个参数考虑在内。
请注意,尽管在 ES5 中 Object.create
支持设置为[[Prototype]]
为null
,但因为那些ECMAScript5以前版本限制,此 polyfill 无法支持该特性。
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 | Status | Comment |
---|---|---|
ECMAScript 5.1 (ECMA-262)The definition of 'Object.create' in that specification. | Standard | Initial definition. Implemented in JavaScript 1.8.5. |
ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Object.create' in that specification. | Standard | |
ECMAScript Latest Draft (ECMA-262)The definition of 'Object.create' in that specification. | Living Standard | |
浏览器兼容
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic Support | 5 | (Yes) | 4 | 9 | 11.6 | 5 |
Feature | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
Basic Support | (Yes) | (Yes) | (Yes) | 4 | (Yes) | 11.5 | (Yes) |