2012-08-30 46 views
2

我想創建一個類常量,但我想我的新手級JavaScript理解顯示。當這個代碼執行:爲什麼需要通過實例訪問原型?

var Class = function() {}; 
Class.prototype = { CONST : 1 }; 
var instance = new Class(), 
c1 = instance.CONST, 
c2 = Class.CONST; 

結果是c1 === 1c2 === undefined。爲什麼不是c2 === 1? JavaScript沒有查找Class的原型鏈嗎?

+0

我沒有足夠的信心把它放在一個答案中,但我會說,類沒有原型鏈......它是一個構造函數。作爲Class實例的對象具有您使用'Class.prototype = ...'創建的原型鏈。換句話說,'Class.prototype'沒有引用'Class'對象的原型鏈,而是引用'Class'構造函數創建的對象的原型鏈。 – LarsH

+0

@LarsH - 我很確定函數對象有原型鏈。然而,你的評論的第二部分,很多都是澄清的。我正在將'Class'的'prototype'屬性與原型鏈混合在一起。 –

+0

特德,我不否認函數對象有原型鏈......只是A.原型是對象A的原型鏈(我同意​​你的看法)。 – LarsH

回答

4

你試圖做的是什麼將被稱爲其他語言的類靜態方法。
要做到這一點在Javascript中你必須寫

Class.CONST = 1;那麼你就可以Class.CONST;

調用它,如果你試圖用實例方法來訪問它像new Class().CONST,這將是不確定的

返回到您的問題,Class.prototype中的所有內容只能通過對象的實例(即通過new創建)訪問,而不是Class本身。爲什麼?

考慮的new

Function.method('new', function() { 
    var that = Object.create(this.prototype); 
    var other = this.apply(that, arguments); 
    return (typeof other === 'object' && other) || that; 
}); 

第一Object.create(this.prototype)實施創建從this.prototype繼承了一個全新的對象其中U通過Class.prototype = { Const : 1 }聲明,那麼它叫this.apply(that, arguments),它只是用that作爲this打電話給你的聲明類功能變量。然後它返回對象。你可以看到Class函數只是用來通過new將事物填充到新創建的對象中。只有創建的對象才能訪問原型方法。

+1

好的。這就是讓我困惑的原因。我處於(明顯錯誤的)印象中,指派給'Class.prototype'的設置是爲'Class'設置原型。所以如果我沒有錯的話,'prototype'鍵在設置構造函數時有特殊的意義,但它與構造函數本身的原型鏈無關;它只是用來爲實例設置原型鏈。我現在有嗎? (PS,難道你不能簡單地設置'Class.CONST = 1' - 而不是一個函數返回1 - 獲得一個「類常量」?) –

+0

是的,JavaScript只會查找原型鏈的一個通過Object.create()創建的對象,new僅僅是Java程序員的一個語法糖。 Class.CONST = 1很好,Class.Anything只是將Anything附加到Class對象 – yngccc

2

您正試圖訪問構造函數的CONST屬性(Class = function(){})。在您實例化Class之前,CONST將不可用。

關於這對夫妻的良好的聯繫:

+1

最後一個鏈接非常有幫助。它清楚地表明構造函數的'prototype'屬性與函數的原型鏈無關。 MDN文件中似乎缺少一些細節(我在發佈問題之前已閱讀過)。 –

0

Class是一個函數對象。函數對象沒有CONST屬性。它被用來構造一個'Class'對象。 'Class'對象是具有CONST屬性的自定義對象,因爲它是在構造函數中聲明的。

1

簡單的答案是,從實例其構造的公共原型繼承,所以c1具有從Class.prototype(嚴格地說,這是該實例的私有財產[[Prototype]])繼承了CONST屬性。

在另一方面,ClassFunction一個實例,因此它從Function.prototype繼承(即其私人[[Prototype]]Function.prototype),不Class.prototype,所以它不具有CONST屬性。

對象的值[[Prototype]]在構建時設置並且永遠不能更改。用其他對象替換Class.prototype只會影響新的實例。

請注意,在一些較舊的Mozilla瀏覽器(例如Firefox)中,有一個__proto__屬性引用對象的[[Prototype]]並且可以設置,但現在已被棄用。

通常最好不要談論有關javascript的類,因爲它推斷的行爲和功能只能在一定程度上模擬。

相關問題