オブジェクトが配列かどうかを確認する方法は?


2753

文字列のリストまたは単一の文字列を受け入れる関数を記述しようとしています。文字列の場合は、1つのアイテムだけを含む配列に変換したいので、エラーを心配することなくループできます。

では、変数が配列かどうかを確認するにはどうすればよいですか?


以下のさまざまなソリューションを切り上げて、jsperfテストを作成しました。彼らはこれだけ使い、すべての高速だArray.isArray-それはだ、よく支えになりましたし、フレームにまたがって動作します


6
「オブジェクトが配列であるかどうかを確認する」というつもりでしたが、具体的には「オブジェクトが文字列の配列または単一の文字列である」かどうかを確認したいと思います。あなたがそれを見るかどうかわからない?それとも私だけですか?私はもっ​​とこのようなものを考えていました...私はここで何かが足りないのですか?
rr1g0 2015

149
TL; DR - arr.constructor === Array最速です。
ネタ

3
jsben.ch/#/QgYAV-最も一般的な方法のベンチマーク
EscapeNetscape

39
TL; DR-配列。isArray(arr) ES5以降; と$。jQueryのisArray(arr)
OndraŽižka16年

6
何らかの理由でプロトタイプを介してコンストラクターを上書きした場合、arr.constructor === Arrayテストはfalseを返すことに注意してください。Array.isArray(arr)まだtrueを返します。
ガシェル

回答:


979

最近のブラウザでは、次のことができます

Array.isArray(obj)

(Chrome 5、Firefox 4.0、IE 9、Opera 10.5、Safari 5でサポート

下位互換性のために、以下を追加できます

# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }
};

jQueryを使用する場合は、jQuery.isArray(obj)またはを使用できます$.isArray(obj)。アンダースコアを使用する場合、使用できます_.isArray(obj)

異なるフレームで作成された配列を検出する必要がない場合は、単に使用することもできます instanceof

obj instanceof Array

9
これがサポートするブラウザのより完全なリストですArray.isArray
lightswitch05

if (typeof Array.isArray === 'undefined') {変更可能if(!Array.isArray) {
iMatoria

Object.prototype.string.call(obj)オブジェクトがそのSymbol.toStringTag上にある場合、それが価値あるもののためになりすまされる可能性があります。とはいえ、出荷する環境については気づいてSymbol.toStringTagいませんArray.isArrayが、安全なようです。
Benjamin Gruenbaum

5
instanceof Arrayアレイが別のフレームのものである場合、なぜ失敗するのですか?
NobleUplift

16
@NobleUplift:instanceof Array配列が異なるフレームからのものである場合、その異なるフレームからのすべての配列には異なるArrayコンストラクターとプロトタイプがあるため失敗します。互換性/セキュリティ上の理由から、すべてのフレームには独自のグローバル環境があり、これにはグローバルオブジェクトが含まれます。Object1つのフレームのObjectグローバルは、別のフレームのグローバルとは異なります。Arrayグローバルについても同様です。Axel Rauschmayerがこれについて詳しく述べています。
jschoi

1943

Objectのクラスを見つけるためにECMAScript標準で指定されているtoStringメソッドは、fromメソッドを使用することですObject.prototype

if( Object.prototype.toString.call( someVar ) === '[object Array]' ) {
    alert( 'Array!' );
}

またはtypeof、それが文字列かどうかをテストするために使用できます。

if( typeof someVar === 'string' ) {
    someVar = [ someVar ];
}

または、パフォーマンスを気にしない場合はconcat、新しい空の配列に対してaを実行できます。

someVar = [].concat( someVar );

直接クエリできるコンストラクタもあります。

if (somevar.constructor.name == "Array") {
    // do something
}

以下のコメントに投稿されているように、@ TJ Crowderのブログから完全な扱いを確認してください。

このベンチマークをチェックして、どちらの方法がより優れたパフォーマンスを発揮するかを確認してください:http : //jsben.ch/#/QgYAV

@Bharathから、質問にEs6を使用して文字列を配列に変換します。

const convertStringToArray = (object) => {
   return (typeof object === 'string') ? Array(object) : object 
}

と仮定します:

let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']

65
+1うん、toString行く方法の一つです。私はここで少しまとめます:blog.niftysnippets.org/2010/09/say-what.html
TJ Crowder

3
typeof new String('beans') > 'object'
Ben

16
「[object Array]」と入力したくない場合は、Object.prototype.toString.call(someVar)=== Object.prototype.toString.call([])を使用するか、入力しない場合は型を取得するための便利な関数を作成します'Object.prototype.toString.callを入力したくない
Pramod

13
私は「最新のブラウザ」(つまり、IE9 +と他のすべての人)で動作する標準的なArray.isArrayを使用します。そして、古いブラウザのサポートには、MDNdeveloper.mozilla.org/en
David Gilbertson 2013年

21
現代の世界にArray.isArray(obj)
住む

1274

まず、実装が以下をサポートしているかどうかを確認しますisArray

if (Array.isArray)
    return Array.isArray(v);

instanceof演算子を使用して試すこともできます

v instanceof Array

127
v instanceof Arrayv別のフレームで作成された場合(クラスのvインスタンスthatFrame.contentWindow.Array)、falseを返します。
pepkin88 2012年

47
具体的にArray.isArrayは、ECMAScript 5 / Javascript 1.8.5の一部として定義されています。
jevon、2012年

8
本当にシンプルで優れたソリューションですが、isArrayは一部の古いブラウザー(例:IE7およびIE8)と互換性がありません。出典:kangax.github.io/es5-compat-table/#
Wookie88

2
方法:if(Array.isArray)return Array.isArray(v); それ以外の場合はv instanceof Arrayを返します。
lewdev 2015年

1
またはただ:return (Array.isArray && Array.isArray(v)) || (v instanceof Array);
Stijn de Witt

298

jQueryも$.isArray()メソッドを提供します:

var a = ["A", "AA", "AAA"];

if($.isArray(a)) {
  alert("a is an array!");
} else {
  alert("a is not an array!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


27
jQueryは内部でtoStringメソッドを内部的に使用しています。GitHubソース
Jacob Squires 2014

5
@JacobSquires依存します。ここでテストしました。Chromeの最新のjQuery- $.isArray === Array.isArraytrueが返されます。
レナン

3
@Renan:これはjQueryを使用することの良い点です。それは通常、それを行うために最も近代的で最良の方法を使用し、何を使用するかを知るためにすべての機能を自分でチェックする必要はありません。
2015

jQueryはArray.isArray舞台裏で使用しています:github.com/jquery/jquery/blob/master/src/core.js#L211
Sergiu

1
しかし、誰もこの機能にjQueryを使用するつもりはありませんよね?何かが配列かどうかを確認したいので、jqueryをダウンロードするだけではありません:p
Automagisch

106

これは、すべての方法の中で最速です(すべてのブラウザーがサポートされています)。

function isArray(obj){
    return !!obj && obj.constructor === Array;
}

2
あなたが正しい、それは私が質問に含めたテストによると最速です。
mpen

5
この方法を使用することの欠点はありますか?受け入れられたトップアンサーよりもはるかにシンプルで効果的です。
David Meza 2016年

@shinobi-ちょうど好奇心が強い(そして私はこれを頻繁に見たことがあります)-なぜあなたは条件でif (obj && Array === obj.constructor)はなく条件を言いますif (obj && obj.constructor === Array)か?それは英語への翻訳、それからコーディングすることで失われたのですか?たとえば、英語を話す人は一般的に「オブジェクトは存在し、コンストラクタは配列クラスからのものですか?」または技術的な理由はありますか?
同期されていない2016年

function object_type(o){var t = typeof(o);return ((t==="object") && (o.constructor===Array)) ? "array" : t;} /*allows you to */ switch(object_type(o)){ case 'array': break; case 'object' : o.dosomething();}
同期されていない2016年

3
@shinobiはすべて良い。私はそれが安全な習慣からの二日酔いかもしれないと思います-誤って= =の代わりに==を使用した場合、割り当て可能な変数ではないのでコンパイルされません。
同期されていない2016年

47

あなたは、この持っている想像して、以下の配列を

var arr = [1,2,3,4,5];

Javascript(新旧のブラウザ):

function isArray(arr) {
  return arr.constructor.toString().indexOf("Array") > -1;
}

または

function isArray(arr) {
  return arr instanceof Array;
}

または

function isArray(arr) {
  return Object.prototype.toString.call(arr) === '[object Array]';
}

次に、次のように呼び出します。

isArray(arr);

Javascript(IE9 +、Ch5 +、FF4 +、Saf5 +、Opera10.5 +)

Array.isArray(arr);

jQuery:

$.isArray(arr);

角度:

angular.isArray(arr);

アンダースコアとロダッシュ:

_.isArray(arr);

34

Array.isArrayは高速に動作しますが、ブラウザのすべてのバージョンでサポートされているわけではありません。だからあなたは他の人のために例外を作り、普遍的な方法を使うことができます:

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }

3
.toString()からメソッドを取得する必要がありObject.prototypeます。現在window.toString()、同じではないを使用しています。
システム

あなたが正しいです。Chrome window.toStringと同じようObject.prototype.toStringに操作します。
CruorVult 2013

isArrayはまったく高速ではありません。最も遅い方法です。
jemiloii 14

UtilsではなくArrayに追加しないのはなぜですか?(私はあなたが新しい配列オブジェクトに追加のプロパティを必要としないことを知っていますが、それはisArrayをArray.prototypeに追加した場合にのみ起こると思います。)
David Winiecki

27

これをチェックする簡単な関数:

function isArray(object)
{
    return object.constructor === Array;
}

16
それを1行に減らしreturn object.constructor === Arrayます-しかし、これが配列に対してのみtrueを返すことを確信していますか?
mpen 2012

12
すべてのブール式でそれを行うことができます。見たときに気がif(x) return true; else return false狂う:-)たとえ逆であっても、表現を否定する必要があります。
mpen 2012

3
これがgetElementsByTagNameに対してtrueを返さない理由は、その関数の結果が実際には配列ではなくHTMLCollectionであるためです。
Yuval A. 14

6
オブジェクトが未定義またはnullの場合、これはひどく失敗します。
John Henckel、

1
@JohnHenckel私の回答を参照してくださいstackoverflow.com/a/29400289/34806それはあなたの懸念と最初のコメントの両方をすべて1行で考慮しています
Dexygen

17

MDN がここで言うよう

Array.isArrayまたはObject.prototype.toString.callを使用して、通常のオブジェクトと配列を区別します

このような:

  • Object.prototype.toString.call(arr) === '[object Array]'、または

  • Array.isArray(arr)


17

この質問には1行のソリューションしかありません

x instanceof Array

ここで、xは変数です。xが配列の場合はtrueを返し、そうでない場合はfalseを返します。


ずっとすっきりしていて安全です!これまたはtypeof比較。
ChristoKiwi 2017年

これは十分なブラウザサポートを受けているものですか?私はそれが好きです。
Dan Zuzevich 2017

1
残念ながら、「x」が配列などのオブジェクトの{}場合、構文エラーが発生するため、これは実際にはtry / catchなしでは役に立ちません。
abalter

15

変数の型が配列かどうかを確認できます。

var myArray=[];

if(myArray instanceof Array)
{
....
}

1
いくつかの人々はすでに言及しinstanceofました..いくつかの奇妙なシナリオでは失敗すると思います。
mpen 2013年

15

私はあなたが扱っているオブジェクトのタイプをテストする関数を作ります...

function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }

// tests
console.log(
  whatAmI(["aiming","@"]),
  whatAmI({living:4,breathing:4}),
  whatAmI(function(ing){ return ing+" to the global window" }),
  whatAmI("going to do with you?")
);

// output: Array Object Function String

次に、単純なifステートメントを記述できます...

if(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}

12

これは非常に簡単な方法で行います。私のために働く。欠点はありますか?

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)

7
だまされる{isArray:true}
ベルギ

JSON.parse(someDataFromElsewhere).items.isArray(データに応じて)trueを返し、コードを壊す可能性があります。
ロイティンカー、

12

これはコメントを考慮してこの回答を改善しようとする私の試みです:

var isArray = myArray && myArray.constructor === Array;

それはif / elseを取り除き、配列がnullまたは未定義である可能性を説明します


ES5ではコンストラクターは使用できません
TechTurtle 2017


11

jsperfフィドルを2つの代替方法とエラーチェックで更新しました。

'Object'および 'Array'プロトタイプで定数値を定義するメソッドは、他のどのメソッドよりも高速であることがわかります。それはやや驚くべき結果です。

/* Initialisation */
Object.prototype.isArray = function() {
  return false;
};
Array.prototype.isArray = function() {
  return true;
};
Object.prototype._isArray = false;
Array.prototype._isArray = true;

var arr = ["1", "2"];
var noarr = "1";

/* Method 1 (function) */
if (arr.isArray()) document.write("arr is an array according to function<br/>");
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");
/* Method 2 (value) - **** FASTEST ***** */
if (arr._isArray) document.write("arr is an array according to member value<br/>");
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");

これらの2つの方法は、変数が未定義の値をとる場合は機能しませんが、値が確実にある場合は機能します。値が配列であるか単一の値であるかをパフォーマンスを考慮して確認することに関して、2番目の方法は有効な高速メソッドのように見えます。Chromeの「instanceof」よりわずかに高速で、Internet Explorer、Opera、Safari(私のマシン)で2番目に優れた方法の2倍の速さです。


9

私は、人々が何らかの生のJavaScriptアプローチを探していることを知っています。しかし、もっと考えたくない場合は、こちらをご覧ください:http : //underscorejs.org/#isArray

_.isArray(object) 

オブジェクトが配列の場合はtrueを返します。

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

7
「フレームワーク/ライブラリーの別のタグも含まれていない限り、純粋なJavaScriptの回答が期待されます。」
のMichałPerłakowski

5

私が見た中で最高の解決策は、typeofのクロスブラウザーの置き換えです。Angus Crollのソリューションをここで確認してください。

TL; DRのバージョンは下にありますが、この記事はこの問題についての素晴らしい議論なので、時間があれば読んでください。

Object.toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
// ... and usage:
Object.toType([1,2,3]); //"array" (all browsers)

// or to test...
var shouldBeAnArray = [1,2,3];
if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */};

5

ここに私の怠惰なアプローチがあります:

if (Array.prototype.array_ === undefined) {
  Array.prototype.array_ = true;
}

// ...

var test = [],
    wat = {};

console.log(test.array_ === true); // true
console.log(wat.array_ === true);  // false

プロトタイプを「いじる」のは犠牲になることは承知していますが、推奨されるtoString方法よりもパフォーマンスが大幅に優れているようです

注:このアプローチの落とし穴は、境界を越えiframeて機能しないことですが、私のユースケースではこれは問題ではありません。


少なくとも、Ubuntu 64ビットのFF30では、パフォーマンスの点でこれ以上は良くありません
test30

2
wat = {array_: true}オブジェクトにだまされます。
ベルギ2015

@Bergi:はい、それは明白です。設定している場合はobj.array_ = true自分をだますだけです。
namuol

@namuol:私は必ずしも自分をだましているわけではありません。多くの場合、十分な数のオブジェクトが辞書として使用されます。cacheプロパティ文字列として検索文字列を使用する検索結果をメモするオブジェクトを考えてください。ユーザーが検索するとどうなりますarray_か?そのため、オブジェクトは配列になりますか?それは単なるバグです。
Bergi

@namuol:また、このアプローチでは、すべての関係者(使用済みライブラリを含む)が.array_配列のタグ付けに使用されることに同意する必要があります。これは実際にはそうではありません、.array何を意味する可能性があります。少なくとも説明的な文字列を使用し、任意の使用の不適切さを通知する必要があり.__isArray = trueます。
Bergi

5

Stoyan Stefanovの著書JavaScript Patternsには、考えられるすべての問題を処理し、ECMAScript 5のメソッドArray.isArray()を利用することを想定した素晴らしい例があります。

だからここにあります:

if (typeof Array.isArray === "undefined") {
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
}

ちなみに、jQueryを使用している場合は、メソッド$ .isArray()を使用できます。


2
+1:なぜ単純なだけではないのif(!Array.isArray) {...ですか?
Marco Demaio 2014

5

オブジェクトが配列かどうかを確認する最も簡単で最速の方法。

 var arr = [];
  arr.constructor.name ==='Array'  //return true;

または

arr.constructor ===Array //return true;

または、ユーティリティ関数を作成できます。

function isArray(obj){ return obj && obj.constructor ===Array}

使用法:

isArray(arr); //return true

5

オブジェクトにconcatメソッドがないことがわかっている場合は、以下を使用できます。

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It's an array");
}


これは良いトリックですが、オーバーライドすることができます...しかし、ほとんどの場合、結果が得られるはずです
Alireza

5

あなたはisArrayメソッドであるかもしれませんが、私はチェックしたいと思います

Object.getPrototypeOf(yourvariable) === Array.prototype


なぜこれを好みますか?
mpen 2018

@mpen Object.getPrototypeOf(yourvariable)は、Arrayオブジェクトのプロトタイプを返します。そして、コードは最も速く、信頼できます。
STEEL

1
失敗するのは簡単です。pastebin.com / MP8d5bCEまた、「最速」の主張を裏付けるパフォーマンステストはありますか?
mpen

4

この関数に渡される可能性のある2種類の値が文字列または文字列の配列のみである場合は、単純にしtypeofて、文字列の可能性のチェックを使用します。

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}

うん...それはこのシナリオではうまくいきますが、一般的にはうまくいきません。とにかくvarargsを使用してしまいました。:)
mpen 2011年

4
A = [1,2,3]
console.log(A.map==[].map)

ここで最短バージョンを探して、これが私が今までに得たものです。

常にすべての可能な組み合わせを検出する完璧な機能はありません。魔法のツールを期待するよりも、ツールのすべての能力と制限を知っている方が良いです。


1
私のわずかな派生ですA.map !== undefinedが、ええ、それは猿の
パッチの

参考:これはiFrame(stackoverflow.com/questions/460256/…)では機能しません
WiredPrairie 2013年

4
function isArray(value) {
    if (value) {
        if (typeof value === 'object') {
            return (Object.prototype.toString.call(value) == '[object Array]')
        }
    }
    return false;
}

var ar = ["ff","tt"]
alert(isArray(ar))


4

あなたはこれを試すことができます:

var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();

arr.constructor.prototype.hasOwnProperty('push') //true

obj.constructor.prototype.hasOwnProperty('push') // false

4

この関数は、ほとんどすべてを配列に変換します。

function arr(x) {
    if(x === null || x === undefined) {
        return [];
    }
    if(Array.isArray(x)) {
        return x;
    }
    if(isString(x) || isNumber(x)) {
        return [x];
    }
    if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
        return Array.from(x);
    }
    return [x];
}

function isString(x) {
    return Object.prototype.toString.call(x) === "[object String]"
}

function isNumber(x) {
    return Object.prototype.toString.call(x) === "[object Number]"
}

いくつかの新しいブラウザー機能を使用しているため、最大限にサポートするためにこれをポリフィルすることができます。

例:

> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]

NB文字列は、文字の配列ではなく、単一の要素を持つ配列に変換されます。isString逆にしたい場合は、チェックを削除します。

これはArray.isArray最も堅牢で最も単純であるため、ここで使用しました。


4

あなたの場合、配列だけでなく単一のオブジェクトも受け入れることができる配列のconcatメソッドを使うことができます:

function myFunc(stringOrArray)
{
  var arr = [].concat(stringOrArray);

  console.log(arr);

  arr.forEach(function(item, i)
  {
    console.log(i, "=", item);
  })
}

myFunc("one string");

myFunc(["one string", "second", "third"]);

concat Arrayの最も古いメソッドの1つであるようです(IE 5.5でもそれをよく知っています)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.