Array.isArray
Firefoxでしか確認してないけど、Array.isArray
メソッドの優位性を知ったのでメモ。
<iframe id="testFrame" src="about:blank">
var iframe = document.getElementById("testFrame"); var doc = iframe.contentDocument; var s = doc.createElement("script"); s.textContent = "var hogehoge = [0,1,2,3,4,5,6]"; doc.body.appendChild(s); var array = iframe.contentWindow.hogehoge;
まあ、重要なのは別ドキュメント内で作られたArrayインスタンスがあること。ここでは、変数arrayが別ドキュメント内のArrayインスタンス。
これが、Arrayインスタンスであることを確認するために
array instanceof Array
などとするとfalse
が返る
理由は後で説明。
替わりにArray.isArray
メソッドを使うと良い感じ。
Array.isArray(array) // true
どういうこと?
仕様を確認してみましょう。
instanceof 演算子
- 11.8.6 The instanceof operator
- 最終的に内部メソッド
[[HasInstance]]
を呼んでいる。
- 最終的に内部メソッド
- 15.3.5.3 [[HasInstance]]
- まぁ要するにプロトタイプを比較して一致なら true を返す仕組み
変数arrayは別ドキュメントのArray.prototypeを参照しており、現ドキュメントのArray.prototypeとは別オブジェクトであったから、先ほどのは false を返したというわけ。
array instanceof iframe.contentWindow.Array
きちんとiframe内のArrayで比較してあげれば、true
が返る。
はい、面倒ですね。
Array.isArray メソッド
- 15.4.3.2 Array.isArray ( arg )
- 内部プロパティ
[[Class]]
が "Array" であるかどうかを判定
- 内部プロパティ
こちらは、プロトタイプが一致するかなどという比較はせずに文字列比較(?)なのでOKであった、というわけ。
ただ、プロトタイプ汚染がされていたとき、むやみにメソッドを使うと怪しい動きをするリスクはあるかも。