Re: ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ
Array.isArray
ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ
MDN: isArray
ECMAScript 5で追加になったArray.isArrayを使えば大丈夫。
非対応ブラウザでも使用可能なコードが紹介されています。
紹介されている、MDN(Mozilla Developer Network)のコードが不適切と思われたので修正しました。-> https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/Array/isArray#.E4.BA.92.E6.8F.9B.E6.80.A7
Google先生にお聞きすると次のコードにも出会いました。
stackoverflow: How to detect if a variable is an arrayObject.prototype.toString.call(obj) === '[object Array]'ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ
こちらの方がより適切なコードです。
何故か
Array.isArrayの挙動
15.4.3.2 Array.isArray ( arg )
- If Type(arg) is not Object, return false.
- If the value of the [[Class]] internal property of arg is
"Array"
, then return true.- Return false.
というのがネイティブの挙動です。重要なのは[[Class]]という内部プロパティが"Array"
であるかを比較している部分。
ダメな方
Array.isArray = function (vArg) { return vArg.constructor === Array; };
constructor
がArray
と同値であるかで判断してますが、
constructor
プロパティが本当にそのオブジェクトのコンストラクタであるかの保障はない- 別コンテキスト(他のiframe内のとか)のArrayオブジェクトの場合、
false
を返してしまう
などの点で挙動がことなります
良い方
Array.isArray = function (vArg) { return Object.prototype.toString.call(vArg) === "[object Array]"; }
こちらはObject.prototype.toString
を使用して文字列比較する方式。
15.2.4.2 Object.prototype.toString ( )
- If the this value is undefined, return "[object Undefined]".
- If the this value is null, return "[object Null]".
- Let O be the result of calling ToObject passing the this value as the argument.
- Let class be the value of the [[Class]] internal property of O.
- Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Object.prototype.toString
は、this
となるオブジェクトの内部プロパティ[[Class]]をとって来て、"[object class]"
を返す挙動です。
Array.isArrayと同じ[[Class]]を使用しています。よってネイティブと同じ挙動を望めるでしょう。引用基はECMAScript 5thの仕様ですが、3rd でもほぼ同じ仕様であることは確認しています。