[解決済み] 変数が配列であるかどうかを検出する方法
質問
JavaScript の変数が配列であるかどうかを判断するための、事実上の標準的なクロスブラウザの方法は何でしょうか?
ウェブを検索すると、多くの異なる提案がありますが、いくつかは良く、かなりの数は無効です。
たとえば、次のようなものが基本的なアプローチです。
function isArray(obj) {
return (obj && obj.length);
}
ただし、配列が空であったり、objが実際には配列ではなくlengthプロパティを実装している場合などはどうなるかに注意しましょう。
では、実際に動作し、クロスブラウザであり、なおかつ効率的に実行できるという点で、どの実装が最も優れているのでしょうか?
どのように解決するのか?
JSにおけるオブジェクトの型チェックは
instanceof
によって行われます。
obj instanceof Array
オブジェクトがフレームの境界を越えて渡される場合、これはうまくいきません。なぜなら、各フレームはそれぞれ
Array
オブジェクトを持つためです。これを回避するには、内部の
[[クラス]]をチェックすることです。
プロパティを確認することで回避できます。これを取得するには
Object.prototype.toString()
(を使用します(これはECMA-262で動作が保証されています)。
Object.prototype.toString.call(obj) === '[object Array]'
どちらのメソッドも実際の配列に対してのみ動作します。
arguments
オブジェクトやノードリストのような配列に似たオブジェクトではありません。すべての配列のようなオブジェクトは数値の
length
プロパティを持たなければならないので、このようにチェックします。
typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number'
なお、文字列はこのチェックを通過してしまいますが、IEではインデックスによる文字列のアクセスができないため、問題が発生する可能性があります。そのため
typeof obj !== 'undefined'
を
typeof obj === 'object'
とは異なる型を持つプリミティブやホストオブジェクトを除外するために
'object'
とは異なる型を持つプリミティブやホストオブジェクトを完全に除外します。これは、手動で除外しなければならない文字列オブジェクトをまだ通過させます。
ほとんどの場合、実際に知りたいことは、数値インデックスを使ってオブジェクトを反復処理できるかどうかです。したがって、オブジェクトが
0
という名前のプロパティがあるかどうかを確認するのが良いかもしれません。
typeof obj[0] !== 'undefined' // false negative for `obj[0] = undefined`
obj.hasOwnProperty('0') // exclude array-likes with inherited entries
'0' in Object(obj) // include array-likes with inherited entries
オブジェクトへのキャストは、配列のようなプリミティブ(例えば文字列)に対して正しく動作するために必要です。
JSの配列に対する堅牢なチェックのためのコードは以下の通りです。
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
と反復可能な(つまり空でない)配列のようなオブジェクトです。
function isNonEmptyArrayLike(obj) {
try { // don't bother with `typeof` - just access `length` and `catch`
return obj.length > 0 && '0' in Object(obj);
}
catch(e) {
return false;
}
}
関連
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列からArrayListを作成する
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】配列に何かを追加する方法は?
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] JavaScriptで、ある文字列が別の文字列の中に出現するすべてのインデックスを見つけるにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] オブジェクトが配列であるかどうかを確認するにはどうすればよいですか?[重複]。
-
[解決済み] JavaScriptで変数が配列であるかどうかを確認する方法は?
-
[解決済み] AngularJSでビュー/部分固有のスタイリングを含む方法
-
[解決済み] Angularjs - 現在の日付を表示する
-
[解決済み] JavaScriptのtoString()関数をオーバーライドして、デバッグ用に意味のある出力を提供することは可能でしょうか?
-
[解決済み] JavaScript のオブジェクトの配列を比較し、最小値/最大値を取得する
-
[解決済み] ECMAScriptとは?
-
[解決済み] jQueryで入力ファイルが空かどうかをチェックする方法
-
[解決済み] なぜjavascriptのES6 Promisesはresolve後も実行を継続するのですか?
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?