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:
new之后,o1有了Base的全部属性,所以o1.a 的值是2;由于Object.create传入的参数是构造函数,o2的_proto_是无法指向Base的,由以上步骤可知o2本身是由一个空构造函数实例化出来的,也不具有a属性,所以输出undefined。
例子2:
可以看到,此时o2去原型链上找a属性,o2的_proto_(原型链)指向的是Base2,所以访问到属性a的值为1。