Object.create()
Object.creat() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
语法:
1 Object.create(proto[, propertiesObject])
参数:
proto:新创建对象的原型对象
propertiesObject:可选。如果没有指定为undefined,则是要添加到新创建对象的不可枚举(默认)属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。
返回值: 一个新对象,带着指定的原型对象和属性
例外:如果propertiesObject参数是null或非原始包装对象,则抛出一个TypeError异常。
使用Object.create()实现类式继承
1 //Shape - 父类(superClass) 2 function Shape() { 3 this.x = 0; 4 this.y = 0; 5 } 6 7 8 //父类的方法 9 Shape.prototype.move = function(x, y) { 10 this.x += x; 11 this.y += y; 12 console.info('Shape moved.'); 13 }; 14 15 //Rectangle - 子类(subclass) 16 function Rectangle() { 17 Shape.call(this); //call super constructor 18 } 19 20 //子类继承父类 21 Rectangle.prototype = Object.create(Shape.prototype); 22 Rectangle.prototype.constructor = Rectangle; 23 24 var rect = new Rectangle(); 25 26 console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); //true 27 console.log('Is rect an instance of Shape?', rect instanceof Shape); //true 28 rect.move(1, 1); //'Shape moved.'
如果希望能继承到多个对象,则可以使用混入的方式
1 function MyClass() { 2 SuperClass.call(this); 3 OtherSuperClass.call(this); 4 } 5 6 //继承一个类 7 MyClass.prototype = Object.create(SuperClass.prototype); 8 //混合其它 9 Object.assign(MyClass.prototype, OtherSuperClass.prototype); 10 11 //重新指定constructor 12 MyClass.prototype.constructor = MyClass; 13 14 MyClass.prototype.myMethod = function() { 15 //do something 16 };
Object.assign 会把 OtherSuperClass 原型上的函数拷贝到 MyClass 原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。
使用 Object.create() 的 propertyObject 参数
1 var o; 2 3 //创建一个原型为 null 的对象 4 o = Object.create(null); 5 6 7 o = {}; 8 //以字面量方式创建的空对象就相当于: 9 o = Object.create(Object.prototype); 10 11 o = Object.create(Object.prototype, { 12 //foo会成为所创建对象的数据属性 13 foo: { 14 writable:true, 15 configurable: true, 16 value: "hello" 17 }, 18 //bar 会成为所创建对象的访问器属性 19 bar: { 20 configurable: false, 21 get: function() { return 10}, 22 set: function(value) { 23 console.log("Setting ` o.bar` to", value); 24 } 25 } 26 }); 27 28 function Constructor() {} 29 o = new Constructor(); 30 //上面的一句就相当于: 31 o = Object.create(Constructor.prototype); 32 //当然,如果在Constructor函数中有一些初始化代码,Object.create()不能执行那些代码 33 34 35 //创建一个以另一个空对象为原型,且拥有一个属性p的对象 36 o = Object.create({}, {p: {value: 42} }) 37 38 //省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的: 39 o.p = 24 40 o.p // 42 41 42 43 o.q = 12; 44 for(var prop in o) { 45 console.log(prop); 46 } //"q" 47 48 delete o.p //false 49 50 //创建一个可写的,可枚举的,可配置的属性p 51 o2 = Object.create({}, { 52 p: { 53 value: 42, 54 writable: true, 55 enumerable: true, 56 configurable: true 57 } 58 });