2012-01-31 41 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