Re: ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ

Array.isArray
MDN: isArray
ECMAScript 5で追加になったArray.isArrayを使えば大丈夫。
非対応ブラウザでも使用可能なコードが紹介されています。

ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ

紹介されている、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 array

Object.prototype.toString.call(obj) === '[object Array]'
ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい « イナヅマtvログ

こちらの方がより適切なコードです。

何故か

Array.isArrayの挙動
  1. If Type(arg) is not Object, return false.
  2. If the value of the [[Class]] internal property of arg is "Array", then return true.
  3. Return false.
15.4.3.2 Array.isArray ( arg )

というのがネイティブの挙動です。重要なのは[[Class]]という内部プロパティが"Array"であるかを比較している部分。

ダメな方
Array.isArray = function (vArg) {  
  return vArg.constructor === Array;  
};  

constructorArrayと同値であるかで判断してますが、

  • constructorプロパティが本当にそのオブジェクトのコンストラクタであるかの保障はない
  • 別コンテキスト(他のiframe内のとか)のArrayオブジェクトの場合、falseを返してしまう

などの点で挙動がことなります

良い方
Array.isArray = function (vArg) {
  return Object.prototype.toString.call(vArg) === "[object Array]";
}

こちらはObject.prototype.toStringを使用して文字列比較する方式。

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
15.2.4.2 Object.prototype.toString ( )

Object.prototype.toStringは、thisとなるオブジェクトの内部プロパティ[[Class]]をとって来て、"[object class]"を返す挙動です。

Array.isArrayと同じ[[Class]]を使用しています。よってネイティブと同じ挙動を望めるでしょう。引用基はECMAScript 5thの仕様ですが、3rd でもほぼ同じ仕様であることは確認しています。