2012-10-31 57 views
6

我閱讀過用於ES6草案,我注意到本說明中Object.prototype.toString部分:接入[[NativeBrand]]/[[類]在ES6(ECMAScript中6)

在歷史上,該功能偶爾用於訪問本規範以前的 版本中使用的[[Class]]內部屬性的字符串 值,作爲各種 內置對象的標稱類型標記。 toString的這個定義保留了將它用作這些特定種類的內置對象的可靠測試的能力,但它並不爲其他 類型的內置或程序定義對象提供可靠的類型測試機制。

從閱讀this thread ES-討論,這聽起來像[[Class]]被用在ES6草案[[NativeBrand]]更換,使他們能夠作爲非擴展的(那些是至少Allen Wirfs-Brock's thoughts)指定。

好奇,我跑在Firefox和Chrome快速測試(試驗啓用JavaScript):

Object.prototype.toString.apply(new WeakMap()); 
=> '[object WeakMap]' 

"WeakMap"不在ES6草案規定的[[NativeBrand]] S的一個。但是,此測試在兩個瀏覽器上返回"[object WeakMap]"

所以我很困惑。我有幾個問題。


1. Chrome和Firefox的行爲是否正確?

從閱讀草稿的方式來看,它聽起來像是應該返回[object Object](所有這些都很新穎,所以在這些瀏覽器的未來版本中看到這種變化並不會感到驚訝)。但是,我很難理解草案的這一部分的意圖,特別是因爲有一些地方"???"

是否有誰一直跟着es討論更熱烈地有任何相關的信息?或者誰能​​更好地理解草稿語言?


2.是否有Object.prototype.toString替代?

從上面引用的註釋中可以看出,Object.prototype.toString是因爲遺留原因保留下來的,好像現在應該使用新的東西來代替。特別是讀取"it does not provide a reliable type testing mechanism for other kinds of built-in ... objects"的節點部分。這是否意味着未來的內置插件無法使用此方法進行測試?

讓我們用一個具體的例子。

如果我要確保我已經從未知源接收的對象是String對象(實際構建String對象,而不是原始的字符串),我可以這樣做:

if (Object.prototype.toString.apply(unknownObject) != '[object String]') 
    throw new TypeError('String object expected.'); 

這讓我知道如果unknownObjectString對象,則無論它構建的是什麼框架。

我的問題是,這應該是我進入ES6的方法嗎?還是有其他選擇嗎?像Object.getNativeBrandOf


3.由於[[NativeBrand]]好像它不包括未來類型的對象,如何將一個測試這些對象?

這項工作?

if (Object.prototype.toString.apply(unknownObject) != '[object Symbol]') 
    throw new TypeError('Symbol expected.'); 

...假設Symbol是專用名稱的最終名稱。

我應該用這個嗎?

if (Object.prototype.toString.apply(unknownObject) != '[object WeakMap]') 
    throw new TypeError('WeakMap expected.'); 

...還是別的什麼?


我之所以問的是我目前正在寫,我希望能夠在可能的時候儘可能輕鬆地過渡到ES6在一年或兩年的代碼。如果有Object.prototype.toString的替代品,那麼我可以將其填入並繼續。謝謝!


更新

benvie的回答給我提供了正確的詞來搜索和了解的回答我的問題。

我發現an email from Allen Wirfs-Brock on es-discuss與此問題有關。

這裏是我的發現,爲別人問同樣的問題:

1.執行Chrome和Firefox的行爲是否正確?

是的,爲什麼說明如下。

2.是否有替代Object.prototype.toString

因爲它是現在,也將在可能性意義上的夫妻「替代品」,而不是在更換感。

a。使用@@toStringTag符號。但是,我的理解是Object.prototype.toString仍應該可能被使用。提供了@@toStringTag以允許擴展可從Object.prototype.toString返回的結果。如果你有一個原型,你想添加自己的字符串標籤,你可以使用@@toStringTag來設置任何字符串的值。 Object.prototype.toString將返回此值,但在此值爲ES5內置插件之一的情況下,此時字符串標籤將預置爲'〜'。

b。在用戶定義的對象上使用私有符號。我讀了一封電子郵件,宣傳這是對用戶定義的對象執行相同類型檢查的最佳方式。然而,我不明白這是如何真正解決問題的,因爲我不明白它是如何成爲一個跨框架解決方案的,並且它不會讓您檢查ES6內置插件。

所以即使有一些替代品,這是很好的堅持與Object.prototype.toString當前和未來,有一點需要注意:

它會工作,以確保你有一個內置的ES5,如String,但要確保你有內置的ES6是不夠的,因爲他們可能被@@toStringTag欺騙。我不確定這是爲什麼,我可能會錯過一些東西,或者隨着規範的發展它可能會改變。

3.由於[[NativeBrand]]好象不會包含將來的對象類型,所以如何測試這些對象?

如上所述,Object.prototype.toString仍然可以在ES6內置插件使用,但它不是防呆,因爲它可以由任何人訪問@@toStringTag符號被欺騙。但是,也許不應該有一種方法,因爲Object.prototype.toString(weakmap) == '[object WeakMap]'並不意味着weakmap instanceof WeakMap(它不應該!)。 weakmap可能來自另一個框架,或者它可能是用戶創建的類似於弱地圖的對象。你唯一真正知道的是報告在功能上等同於WeakMap。

它似乎乞求的問題,爲什麼你不能有一個用戶定義的對象,報告功能等效於StringArray(無前綴"~")。

+0

回答的最後一個問題(約〜等)是有依賴於現有的網絡上現有的代碼OptoString結果值對於現有的ES5內置插件不具有欺騙性。我們希望保持該保證,但僅限於O.p.toString在ES <= 5中知道的對象/ [[Class]]值。 –

+0

'〜'步驟被rev 32刪除。 – Knu

+0

「這讓我知道如果unknownObject是一個String對象,無論它構造了什麼框架。」不在Opera中。 – Knu

回答

1

這是目前ES6規範中的移動目標。對於現有的一組對象,由於各種原因(包括兼容性)而維護現有的機制。在最近的ES6規範,published October 26th,你可以找到未來的潛在方向

15.4.6.2.4ArrayIterator.prototype的一些提示。@@ toStringTag
的初始值@@ toStringTag屬性是 字符串值「Array Iterator」。

15.14.5.13Map.prototype。@@ toStringTag
的@@ toStringTag屬性的初始值是字符串值 「地圖」。

您可以找到產生此in this thread原始討論ES-討論

+0

謝謝,指出我在正確的方向,並給了我需要的術語。我已經用上面更完整的答案更新了我的問題,爲了後代。 –