为什么这两个实现的行为不同?在评估他们的原型时,究竟是什么让他们与众不同?
使用指定的原型创建对象:
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
?
答案 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关键字。