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() æå®å
¶ååç©ä»¶è屬æ§ï¼åµå»ºä¸åæ°ç©ä»¶ã
èªæ³
Object.create(proto[, propertiesObject])
忏
proto-
æå®æ°ç©ä»¶çåå (prototype) ç©ä»¶ã
propertiesObject-
é¸ç¨ï¼çºä¸ç©ä»¶ã妿æå®ä¸é
undefinedï¼åæ¤åæ¸ç©ä»¶ä¸å¯åèåºçå±¬æ§ (å³åæ¸ç©ä»¶èªèº«å®ç¾©ç屬æ§ï¼ä¸¦éæååéä¸çenumerableç¹æ§ ) å°æå ¶å±¬æ§åç¨±ï¼æ ¹æå ¶å±¬æ§æè¿°å (property descriptors) å 鲿°åµå»ºçç©ä»¶ãéäºå±¬æ§å°æå°Object.defineProperties()ç第äºå忏ã
åå³
å ·ææå®ååç©ä»¶è屬æ§çæ°ç©ä»¶ã
ä¾å¤
妿 proto 忏䏿¯ null æä¸åç©ä»¶ï¼å°ææåº TypeError ä¾å¤ã
ç¯ä¾
>ä½¿ç¨ 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); // true
console.log("Is rect an instance of Shape?", rect instanceof Shape); // true
rect.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 æªå®ç¾©ï¼é è¨ççº false
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ï¼ä½å¨ 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® 2027 Language Specification> # sec-object.create> |
ç覽å¨ç¸å®¹æ§
åé±
Object.defineProperty()Object.defineProperties()Object.prototype.isPrototypeOf()- John Resig's post on getPrototypeOf()