2012-01-31 39 views
21

我最近开始对OOP javascript和一件事读了,作者似乎跳过是当一个对象A已经宣布,突然我看到“A.prototype.constructor = A; 例如,为什么OOP JavaScript中使用object.prototype.constructor?

var A = function(){}; // This is the constructor of "A" 
A.prototype.constructor = A; 
A.prototype.value = 1; 
A.prototype.test = function() { alert(this.value); } 
var a = new A(); // create an instance of A 
alert(a.value); // => 1 

所以我跑的萤火命令“变种A =函数(){};”。 ,然后“A.Constructor”揭示它是一个功能我明白这
我运行代码“A.prototype。构造函数= A;“我认为这将A构造函数从Function更改为A.

A的构造函数属性chan ged对不对?相反,当我运行“A.constructor”它仍然给我function()。

有什么意义?

我也看到A.constructor.prototype.constructor.prototype ...到底是怎么回事?

+6

哪些作者,在哪里? – 2012-01-31 05:04:47

+0

我得到这个代码是http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures – Matt 2012-02-01 03:00:01

回答

12

如果A继承B使用A.prototype = new B();,你需要重置使用A.prototype.constructor=A; A类constructor属性,否则的情况下,将有B.

的构造你的情况,A.prototype.constructor === A将返回true,那么A.prototype.constructor = A什么也没做。

+0

有趣所以A.prototype.constructor = A;会使A与B隔离吗?这样,您可以使用A.prototype扩展更多的属性,而无需向B添加更多属性? – Matt 2012-02-02 08:12:14

+0

这与隔离无关,只是确保A具有正确的构造函数属性。 – xdazz 2012-02-02 09:42:35

+11

拥有正确的构造函数属性的目的是什么? A.prototype.constructor在实际中曾经实际咨询过什么时候?它似乎不会影响创建A,afaics的新实例的行为。答案一定是如此明显,以至于一般都没有说明,这就是为什么它没有了我:-) – Yetanotherjosh 2013-07-30 06:40:20

4

可以快速测试的是额外的任务绝对没有:

var A = function() {}; 
A.prototype.constructor === A; // true -- why assign then? 

重置constructor属性才有意义,如果您分配一个新的原型对象的类,覆盖原来的构造函数:

var A = function() {}; 
A.prototype = protoObject; // some object with members that you'd like to inherit 
A.prototype.constructor = A; // reset constructor 

对于您的情况,作者可能会盲目地将其作为良好做法,即使在没有必要的情况下也是如此。

2

此代码,如果在JS经典的遗传模式经常使用(代码是从JavaScript模式由斯托扬斯特凡):

function inherit(C, P) { 
    var F = function() {}; 
    F.prototype = P.prototype; 
    C.prototype = new F(); 
    C.uber = P.prototype; 
    C.prototype.constructor = C; 
} 

向右构造函数分配到子类。

在你的情况下,它没有做任何事情,因为A.prototype.constructor === A在分配之前。

1

你可能想看看我的回答类似的问题:

https://stackoverflow.com/a/19616652/207661

TL; DR:构造函数是不是自己的实例的属性。所以为了让事情看起来一致,JavaScript解释器需要设置prototype.constructor自身的功能。此功能可用于一般在许多不同类型的对象上运行的功能。

1

根据MDN,所有的物体从他们的原型继承constructor属性:

Example 1: 
var o = {}; 
o.constructor === Object; // true 

..

Example2: 
function Tree() { 
}  
var theTree = new Tree(); 
console.log(theTree.constructor === Tree); // true 

在运行时,它基于构造函数属性的值没有任何区别。

但是,由于构造函数属性返回对创建实例原型的Object函数的引用,因此应该在将新原型分配给Object函数时重置构造函数属性。

var Forest = function() {}; 
Forest.prototype = theTree; 
console.log(new Forest().constructor === Tree); // true 
Forest.prototype.constructor = Forest; 
console.log(new Forest().constructor === Forest); // true 

https://jsfiddle.net/j1ub9sap/

详情:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

+0

嗨,几个月后,我跳过你的评论,因为我不明白这句话:“然而,由于构造函数属性返回对创建的对象函数的引用实例的原型“ Object函数不会创建实例的原型,它直接创建实例no?这究竟意味着什么?谢谢 – jobou 2016-07-07 12:46:55

+0

这意味着如果Forest使用Forest.prototype = new theTree()继承Tree,则Forest的实例将拥有Tree的构造函数。 要将Forest作为构造函数,需要使用Forest.prototype.constructor = Forest重置Forest的构造函数属性。 – 2016-07-07 23:00:11

+0

我明白你的例子。我的问题更多的是官方文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor它说:“返回对创建实例的Object函数的引用原型。”。但是,此页面中的所有示例都没有覆盖原型。没有自定义继承:'var a = []; a.constructor === Array;'那么为什么不说“构造函数是对创建实例本身的Object函数的引用”?谢谢 – jobou 2016-07-08 07:50:02