为什么Object.create()和new Object()会评估不同的原型?

时间:2015-04-12 19:15:21

标签: javascript prototype instantiation

为什么这两个实现的行为不同?在评估他们的原型时,究竟是什么让他们与众不同?

使用指定的原型创建对象:

   function Foo() {}

   // creates an object with a specified prototype
   var bar = Object.create(Foo);

   console.log(Object.getPrototypeOf(bar)); // returns: function Foo(){}
   console.log(Foo.isPrototypeOf(bar)); // returns: true

使用构造函数方法创建对象:

   function Foo() {}

   // creates an object with the constructor method    
   var bar = new Foo();

   console.log(Object.getPrototypeOf(bar)); // returns: Foo {}
   console.log(Foo.isPrototypeOf(bar)); // returns: false

另外,为什么第二个实现同时返回Foo {}false

2 个答案:

答案 0 :(得分:22)

Object.create(Foo)表示"创建一个以Foo为原型的对象"。

new Foo()表示"创建一个对象,Foo.prototype作为原型,Foo作为构造函数"。

因此,Foo是第一个示例中Bar原型,第二个示例中是Bar构造函数

我认为问题的第二部分是由误导性的控制台输出提示的 - Object.getPrototypeOf(bar)实际上返回Foo.prototype,而不是Foo

function Foo() {}
var bar = new Foo();

Object.getPrototypeOf(bar) === Foo
// -> false

Object.getPrototypeOf(bar) === Foo.prototype
// -> true

答案 1 :(得分:11)

当您使用' new'用于实例化对象的关键字JavaScript实际上会在您的对象中添加两行代码。

如果您打算使用伪经典实例化创建对象,则可以像这样创建对象:

var Foo = function() {
this.property = 'baz';
};

当您致电var bar = new Foo()时,Javascript按以下方式运行Foo:

var Foo = function() {
// ADDED CODE: var this = Object.create(Foo.prototype);
this.property = 'baz';
// ADDED CODE: return this;

使用Object.create创建从新创建的对象到指定对象的委托关系,因此在第一种情况下,bar将其查找委托给Foo,但在第二种情况下,查找委托给Foo.prototype。

您可能会发现this博文有趣。它进入Pseudoclassical实例化(使用new关键字)而不是Prototypal实例化,它不使用new关键字。