Object.prototype.toString
ES6のドラフトを読んでいたところ、次のセクションでこのメモに気づきました。
歴史的に、この関数は、この仕様の以前のエディションでさまざまな組み込みオブジェクトの名義型タグとして使用されていた[[Class]]内部プロパティの文字列値にアクセスするために使用されることがありました。toStringのこの定義は、これらの特定の種類の組み込みオブジェクトの信頼できるテストとして使用する機能を保持しますが、他の種類の組み込みオブジェクトまたはプログラム定義オブジェクトの信頼できる型テストメカニズムを提供しません。
es-discussでこのスレッドを読んだところ、ES6ドラフト[[Class]]
で置き換えられているよう[[NativeBrand]]
に思われるので、拡張不可能であると指定できます(少なくともAllen Wirfs-Brockの考えでした)。
不思議なことに、FireFoxとChromeで簡単なテストを実行しました(実験的なJavaScriptが有効になっています)。
Object.prototype.toString.apply(new WeakMap());
=> '[object WeakMap]'
"WeakMap"
[[NativeBrand]]
ES6ドラフトで指定されているの1つではありません。ただし、このテストは"[object WeakMap]"
両方のブラウザで返されました。
だから私は混乱しています。少し質問があります。
1. ChromeとFirefoxは正しく動作しますか?
ドラフトを読む1つの方法から、彼らは戻ってくるはずだと思われます[object Object]
(そして、これはすべてかなり新しいので、これらのブラウザーの将来のエディションでこの変更が見られても驚かないでしょう)。ただし、ドラフトのこのセクションの意図を理解するのは難しいです。特に、が付いている場所がいくつかあるため"???"
です。
es-discussをもっと熱心にフォローしている人は、関連する情報を持っていますか?または、ドラフト言語をよりよく理解できる人はいますか?
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.');
これにより、どのフレームで構築されたかに関係なくunknownObject
、がオブジェクトであるかどうかを知ることができます。String
私の質問は、これは私が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.');
... または、他の何か?
私が尋ねる理由は、私が現在、可能な限り1、2年でES6にできるだけ簡単に移行できるようにしたいコードを書いているからです。の代替品がある場合はObject.prototype.toString
、それをシムインしてそこから続行できます。ありがとう!
アップデート
ベンビーの答えは、私の質問に対する答えを検索して理解するための正しい用語を私に提供してくれました。
この問題に関するes-discussのAllenWirfs-Brockからのメールを見つけました。
同じ質問をしている他の人のために、私が見つけたものは次のとおりです。
1. ChromeとFirefoxは正しく動作しますか?
はい、その理由を以下に説明します。
2.代替手段はありObject.prototype.toString
ますか?
現在のように、可能性という意味ではいくつかの「代替」がありますが、代替という意味ではありません。
a。 シンボルを使用します。@@toStringTag
しかし、私の理解では、それObject.prototype.toString
はおそらくまだ使用されるべきであるということです。@@toStringTag
から返すことができる結果を拡張できるようにするために提供されていますObject.prototype.toString
。独自の文字列タグを追加したいプロトタイプがある場合は、を使用@@toStringTag
して値を任意の文字列に設定できます。Object.prototype.toString
この値がES5組み込みの1つである場合を除いて、この値を返します。この場合、文字列タグの前に「〜」が付きます。
b。 ユーザー定義オブジェクトでのプライベートシンボルの使用。ユーザー定義オブジェクトに対して同じタイプのチェックを行うための最良の方法として、これを宣伝する1通の電子メールを読みました。ただし、それがどのように問題を解決するのかはわかりません。クロスフレームソリューションになる可能性があることを理解できず、ES6ビルトインと照合できないためです。
したがって、いくつかの選択肢がありますがObject.prototype.toString
、1つの注意点を除いて、現在および今後も継続することをお勧めします。
などのES5が組み込まれていることString
を確認することはできますが、ES6が組み込まれていることを確認することは、スプーフィングされる可能性があるため、絶対確実ではありません@@toStringTag
。これがなぜなのかわかりません。何かが足りないか、仕様が進化するにつれて変更される可能性があります。
3.[[NativeBrand]]
将来のタイプのオブジェクトは含まれないようですが、これらのオブジェクトをどのようにテストしますか?
上記のように、Object.prototype.toString
ES6ビルトインでも引き続き使用できますが、@@toStringTag
シンボルにアクセスできる人なら誰でもスプーフィングされる可能性があるため、絶対確実ではありません。ただし、それを意味するわけではないので、絶対確実な方法があるべきではないかもしれません(そしてそうすべきではありません!)。は別のフレームからのものであるか、ユーザーが作成したweakmapのようなオブジェクトである可能性があります。あなたが本当に知っている唯一のことは、それがWeakMapと機能的に同等であると報告しているということです。Object.prototype.toString(weakmap) == '[object WeakMap]'
weakmap instanceof WeakMap
weakmap
String
またはArray
(接頭辞がない)と機能的に同等であると報告するユーザー定義オブジェクトを使用できないのはなぜかという疑問を抱いているようです"~"
。