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

Why do Object.create() and new Object() evaluate to different prototypes?

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

正在创建具有指定原型的对象:

   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

此外,为什么第二个实现 return 同时 Foo {}false

Object.create(Foo) 表示 "create an object with Foo as the prototype".

new Foo() 表示 "Create an object with Foo.prototype as the prototype and Foo as the constructor".

因此Foo是第一个例子中Bar原型构造函数 17=]在第二个例子中。

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

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

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

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

当您使用 '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 博客 post 有趣。它进入伪经典实例化(使用 new 关键字)而不是 Prototypal 实例化,后者不使用 new 关键字。