我在看最新的ECMA-262參考,5.1版2011年6月構造函數總是一個函數對象嗎?
在第8.6.2表9中,我們必須在考慮到[建設]]內部屬性:
創建對象。通過新操作員調用。 SpecOp的參數 是傳遞給 新運算符的參數。實現此內部方法 的對象稱爲構造函數。
該標準沒有說構造函數必須是一個Function對象。那麼我們可以有一個不是函數對象的構造函數對象嗎?
Link to the standard as requested
我在看最新的ECMA-262參考,5.1版2011年6月構造函數總是一個函數對象嗎?
在第8.6.2表9中,我們必須在考慮到[建設]]內部屬性:
創建對象。通過新操作員調用。 SpecOp的參數 是傳遞給 新運算符的參數。實現此內部方法 的對象稱爲構造函數。
該標準沒有說構造函數必須是一個Function對象。那麼我們可以有一個不是函數對象的構造函數對象嗎?
Link to the standard as requested
雖然定義了「構造函數」(作爲@RobG pointed out),但沒有任何內容阻止非「構造函數」對象使用方法[[Construct]]
。
這有點令人困惑。這意味着您可以在不是Function
的對象上使用new
運算符(因此不是4.3.4 中的「構造函數」),但的確提供了[[Construct]]
方法。
請注意,沒有任何標準對象符合此條件,但確實可以使用host objects。一個瀏覽器插件,如Java可能會使像這樣一些對象:
new java.lang.String(); // it works, so java.lang.String has a [[Construct]] method
java.lang.String instanceof Function // false
Object.prototype.toString.call(java.lang.String).indexOf('Function') // -1
注意typeof java.lang.String
回報"function"
即使java.lang.String
不是一個函數。根據11.4.3這是正確的(它是一個[[Call]]
方法主機對象)
接下來你會迷失在「什麼是函數?」的語義中。該規範僅涵蓋本地對象(包括內置插件),並明確允許主機對象執行他們喜歡的操作。主機對象的創建者遵循ECMA-262是有道理的,但在很多情況下他們沒有,很高興看到一個不是IE的例子。 :-) – RobG
@RobG不知道你在這裏想說什麼。 [8.6.2](http://es5.github.com/#x8.6.2)在一定程度上覆蓋了主機對象。此外,術語「功能」在[4.3.24](http://es5.github.com/#x4.3.24)中定義 – user123444555621
@RobG我認爲問題在於規格不完全一致。 – Roland
答案非常簡單。 ES5 § 4.3.4說:
Constructor
Function object that creates and initialises objects.
所以你有它,顧名思義只是一個功能可以是一個構造函數。但是,可能有主機對象的行爲與構造函數沒有任何本地函數對象的其他屬性(例如,在ActiveX中實現的IE中的原始XMLHttpRequest對象)一樣。
之間有一個主要區別我接受這個答案。恕我直言規範是不完全清楚的,似乎不是一個函數的對象仍然可以有一個[[Construct]]內部屬性,至少在問題中引用的表9沒有明確禁止這一點。如果有人知道規範的作者是誰,我想給他寫一封電子郵件並要求澄清。 – Roland
你能鏈接到規格文件嗎?如果沒有更完整的上下文,我認爲很多人都無法回答。 (有趣的問題,雖然!) – apsillers
您可能對[Annotated ES5](http://es5.github.com/)感興趣,它是ECMA-262 5.1標準PDF的HTML轉換。它有章節錨,如[8.6.2節](http://es5.github.com/#x8.6.2)。 –
如果我沒有記錯,克羅克福德說,一般來說,使用構造函數不是一個好的模式在JS – thepoosh