Object.create
Object.create
Object.create
, 使用现有的对象来提供新创建的对象的__proto__
1 2 3 4 5 6 7 |
// 语法 Object.create(proto[, propertiesObject]) // proto: 新创建对象的原型对象。 // propertiesObject: 可选。 // 如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。 // 这些属性对应Object.defineProperties()的第二个参数。 |
1 2 3 4 5 6 |
var a = { age: 10 }; var b = Object.create(a); console.log(b); // {} console.log(a); // { age: 10 } console.log(b.__proto__ === a); // true |
用 Object.create实现类式继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// Shape - 父类(superclass) 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 - 子类(subclass) function Rectangle() { Shape.call(this); // call super constructor. } // 子类续承父类 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); } MyClass.prototype = Object.create(SuperClass.prototype); Object.assign(MyClass.prototype, OtherSuperClass.prototype); // 重新指定constructor MyClass.prototype.constructor = MyClass; MyClass.prototype.myMethod = function() { // do a thing }; |
使用 Object.create 的 propertyObject参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
var o; // 创建一个原型为null的空对象 o = Object.create(null); o = {}; // 等同于 o = Object.create(Object.prototype); o = Object.create(Object.prototype, { foo: { writable:true, configurable:true, value: "hello" }, // 访问器属性 bar: { configurable: false, get: function() { return 10 }, set: function(value) { console.log("Setting `o.bar` to", value); } } }); function Constructor(){} o = new Constructor(); // 等同于 o = Object.create(Constructor.prototype); // 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码 // 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的。 o = Object.create({}, { p: { value: 42 } }) o.p = 24 // 执行后,也不会生效 o.p //42 o.q = 12 for (var prop in o) { console.log(prop) } //"q" // o.p, 不可枚举。 for...in循环也访问不到 delete o.p //false //创建一个可写的,可枚举的,可配置的属性p o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } }); |
Polyfill
Object.create
的Polyfill可参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill