Object.create ( proto, [ propertiesObject ] )
第一个参数是是新创建的对象的原型,第二个参数可选,该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)。注意:该参数对象不能是 undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。
首先看他们都做了什么?
new XXX()
var F = function() {}; var f = new F();
1 创建一个空对象:var obj = new Object();
2 将这个新对象的__proto__指向构造函数的prototype:obj.__proto__ = F.prototype;
3 将构造函数的作用域赋值给新对象 (也就是this指向新对象)
4 执行构造函数中的代码(为这个新对象添加属性)
5 返回新的对象
相当于一下代码:
var Obj = {}; Obj._proto_ = Person.prototype(); Person.call(Obj);
Object.create(XXX)
Object.create(Base);
1 创建一个空函数;
2 函数的prototype指向Base函数;
3 new一个函数的实例(即让该实例的_proto_指向函数F的prototype,也就是Base函数,最后将该实例返回)
注意传入的参数Base是一个对象。如果传入的是一个构造函数的话,该实例是无法继承的。
相当于以下代码:
Object.create = function (Base) { var F = function () {}; F.prototype = Base; return new F(); };
例子1:
可以看到,此时o2去原型链上找a属性,o2的_proto_(原型链)指向的是Base2(指向它构造函数的prototype即Base2),所以访问到属性a的值为1。
Object.create = function (Base) { var F = function () {}; F.prototype = Base; return new F(); };
比较 | new | Object.create |
---|---|---|
继承 | 保留原构造函数的属性 | 参数是函数的话会丢失这个函数的属性,参数是对象的话会保留对象的属性 |
_proto_ | 指向原构造函数prototype属性 | 根据参数不同指向原构造函数本身或对象本身 |
作用对象 | function(new的是函数) | function和object(参数是函数或对象) |
Object.cerate() 创建的新对象的原型指向接收的参数本身,new Object() 创建的新对象的原型指向的是 Objec的prototype。
可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object的prototype。
Object.create(o),如果o是一个构造函数,则采用这种方法来创建对像没有意义;
Object.create(o),如果o是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝;