7

我在阅读上的JavaScript花园http://bonsaiden.github.com/JavaScript-Garden/约原型在JavaScript和例子之一是这样的:为什么上市一类的实际构造在JavaScript重要

function Foo() { 
    this.value = 42; 
} 
Foo.prototype = { 
    method: function() {} 
}; 

function Bar() {} 

// Set Bar's prototype to a new instance of Foo 
Bar.prototype = new Foo(); 
Bar.prototype.foo = 'Hello World'; 

// Make sure to list Bar as the actual constructor <------------------- 
Bar.prototype.constructor = Bar; 

通知,上面写着确保线路列表Bar作为实际的构造函数。我真的迷失了这件事。我已经试过在没有最后一行的情况下创建Bar()的新实例。但是在这些实例上调用“值”或“方法”会返回完全相同的结果。所以我想知道,指定构造函数有什么需要(我认为必须有)?

谢谢!!!

回答

6

每个函数都有一个prototype属性,创建函数对象时,它的分配,它指向一个新创建的对象,从Object.prototype继承,它有一个constructor属性,简单地回指向函数本身。

prototype属性的目的是给出一种方法来实现继承,使用构造函数。当您使用new运算符调用函数时,它将创建一个从该构造函数的prototype继承的新对象。现在

,该constructor财产的目的是有办法重新引用已创建的对象的构造函数,例如:

function Foo() {} 
// default value of the property: 
Foo.prototype.constructor == Foo; // true 

此属性是由的Foo“实例”继承,这样你就可以知道哪个构造函数用于创建一个对象:如果您分配一个新的对象给函数的原型

var foo = new Foo(); 
foo.constructor == Foo; 

,这种关系将丢失:

function Bar() {} 
Bar.prototype = { inherited: 1 }; 

Bar.prototype.constructor == Bar; // false 
Bar.prototype.constructor == Object; // true 

而且这也影响了功能的实例:

var bar = new Bar(); 
bar.constructor == Bar; // false 
bar.constructor == Object; // true 

另一个类似的例子是,当你有使用构造继承的两个或两个以上的水平,最常见的方式是用来表示继承关系在功能之间,是指定第二级的属性,例如:

function Parent() {} 

function Child() {} 
Child.prototype = new Parent(); 

上面的代码有几个问题,第一,它执行父构造函数来创建的继承关系的逻辑,但那是另一个故事,在上面的例子中constructor财产也受到影响,因为我们更换完全Child.prototype对象:

var child = new Child(); 
child.constructor == Parent; // true 

如果我们更换分配给它更换后的Child.prototypeconstructor属性的值,它会显示预期的行为:

function Child() {} 
Child.prototype = new Parent(); 
Child.prototype.constructor = Child; 

var child = new Child(); 
child.constructor == Child; // true 
+0

感谢您的详细解释。这一切都有道理。唯一让我感到困惑的东西,但我可以忽略的是它看起来有点儿在Child.prototype.constructor = Child –

+1

@Nik,不客气!是的,这确实是循环设计,例如:'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;';-) – CMS

2

我相信这与用new关键字实例化Bar有关。我相信使用new将查找Bar.prototype.constructor。在该行之前,链接到Bar.prototype.contructor的对象是Foo类型,因此在没有该行的情况下实例化时,它将创建Foo对象而不是Bar对象。

+0

谢谢基思! ;这是一个简洁和重点解释,以及 –

+1

不客气!如果这有助于你可以+1吗? –

相关问题