객체가 배열인지 확인하는 방법?


2752

문자열 목록 또는 단일 문자열을 허용하는 함수를 작성하려고합니다. 문자열 인 경우 하나의 항목으로 배열로 변환하려고하므로 오류에 대한 두려움없이 반복 할 수 있습니다.

그렇다면 변수가 배열인지 어떻게 확인합니까?


아래의 다양한 솔루션을 모아서 jsperf 테스트를 만들었습니다 . 그들은 그래서 그냥 사용, 모든 빠르다 Array.isArray- 그것의 잘 지원 해주기 및 프레임에 걸쳐 작품 .


6
'객체가 배열인지 확인하십시오'라고 생각했지만 '개체가 문자열의 배열인지 단일 문자열인지'를 확인하고 싶습니다. 잘 모르겠다면? 아니면 그냥 나인가요? 나는 이것 과 비슷한 것을 생각하고 있었다 ... 나는 여기에 뭔가 빠진 사람인가?
rr1g0

149
TL; DR은 - arr.constructor === Array가장 빠르다.
Neta

3
jsben.ch/#/QgYAV- 가장 일반적인 방법에 대한 벤치 마크
EscapeNetscape

39
TL; DR- 배열. ES5 이후의 isArray (arr) ; 그리고 $. jQuery의 isArray (arr)
Ondra Žižka

6
어떤 이유로 든 프로토 타입을 통해 생성자를 덮어 쓰면 arr.constructor === Array테스트에서 false가 반환됩니다. Array.isArray(arr)그래도 여전히 true를 반환합니다.
ghaschel

답변:


976

최신 브라우저에서 할 수있는 일

Array.isArray(obj)

( 지원 크롬 5, 파이어 폭스 4.0, IE 9, 오페라 10.5 사파리 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생성자와 프로토 타입 이 있으므로 배열이 다른 프레임에있는 경우 실패합니다 . 호환성 / 보안상의 이유로 모든 프레임에는 고유 한 전역 환경이 있으며 여기에는 전역 개체가 포함됩니다. Object한 프레임 의 글로벌은 다른 프레임 의 글로벌과 다릅니다 Object. Array글로벌 도 마찬가지입니다 . Axel Rauschmayer가 이에 대해 더 이야기합니다 .
jschoi

1943

Object 클래스를 찾기 위해 ECMAScript 표준에 제공된 toString방법은 의 방법 을 사용하는 것입니다 Object.prototype.

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

또는 typeof문자열인지 테스트하는 데 사용할 수 있습니다 .

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

또는 성능이 걱정되지 않으면 concat빈 배열을 새로 만들 수 있습니다 .

someVar = [].concat( someVar );

직접 쿼리 할 수있는 생성자가 있습니다.

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

아래의 의견에 게시 된 @TJ Crowder의 블로그 에서 철저한 치료 를 확인하십시오 .

어떤 벤치 마크 가 더 나은지 알아 보려면 이 벤치 마크 를 확인하십시오 : http://jsben.ch/#/QgYAV

에서 @Bharath의 질문과 대답 (FAQ) 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') > '개체'

16
"[object Array]"를 입력하지 않으려면 Object.prototype.toString.call (someVar) === Object.prototype.toString.call ([])을 사용하거나 편리한 함수를 작성하여 입력하십시오 'Object.prototype.toString.call을 입력하고 싶지 않습니다
Pramod

13
나는 '현대 브라우저'(즉, IE9 + 및 기타 모든 사람)에서 작동하는 vanilla Array.isArray를 사용합니다. 그리고 오래된 브라우저 지원을 위해 MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
David Gilbertson

21
현대 사회에서 라이브 -Array.isArray(obj)
mcfedr

1274

먼저 구현이 지원하는지 확인합니다 isArray.

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

당신은 또한 instanceof연산자를 사용해보십시오

v instanceof Array

127
v instanceof Arrayv다른 프레임에서 작성된 경우 false를 반환 v합니다 ( thatFrame.contentWindow.Array클래스의 인스턴스 임 ).
pepkin88 2019 년

47
구체적으로 말하면 Array.isArrayECMAScript 5 / Javascript 1.8.5의 일부로 정의됩니다.
jevon

8
정말 간단하고 깔끔한 솔루션이지만 isArray는 일부 구형 브라우저 (예 : IE7 및 IE8)와 호환되지 않습니다. 출처 : kangax.github.io/es5-compat-table/#
Wookie88

2
방법 : if (Array.isArray) 반환 Array.isArray (v); 그렇지 않으면 v instanceof Array를 리턴합니다.
lewdev

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 Source
Jacob Squires

5
@JacobSquires에 따라 다릅니다. 방금 Chrome의 최신 jQuery를 테스트했습니다 $.isArray === Array.isArray.
Renan

3
@Renan : 이것은 jQuery 사용에 대한 좋은 것입니다. 일반적으로 가장 현대적이고 최상의 방법을 사용하므로 사용 방법을 알기 위해 모든 기능을 직접 검사 할 필요는 없습니다.
경외

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

@ shinobi-그냥 궁금합니다 (그리고 나는 이것을 자주 보았습니다)-왜 당신 if (obj && Array === obj.constructor)은 반대 조건을 문구로 표현 if (obj && obj.constructor === Array)합니까? 영어로 번역 한 다음 코드를 잃어 버렸습니까? 예를 들어, 영어 사용자는 일반적으로 "객체가 존재하고 생성자가 배열 클래스에서 온 것입니까?" 아니면 기술적 인 이유가 있습니까?
동기화되지 않은

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();}
동기화되지 않은

3
@shinobi 모두 좋아. 안전한 c 습관으로 인해 숙취가 있다고 가정합니다. 실수로 = 대신 ==를 사용하면 할당 가능한 변수가 아닌 것으로 컴파일되지 않습니다.
동기화되지 않은

47

배열이 아래에 있다고 상상해보십시오 .

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

자바 스크립트 (새로운 브라우저 및 이전 브라우저) :

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);

자바 스크립트 (IE9 +, Ch5 +, FF4 +, Saf5 +, Opera10.5 +)

Array.isArray(arr);

jQuery :

$.isArray(arr);

모난:

angular.isArray(arr);

밑줄과 Lodash :

_.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

isArray는 전혀 빠르지 않습니다. 가장 느린 방법입니다.
jemiloii

Utils가 아닌 Array에 추가하지 않는 이유는 무엇입니까? (새로운 배열 객체에 대해 추가적인 속성을 원하지는 않지만 isArray를 Array.prototype에 추가하는 경우에만 발생한다고 생각합니다.)
David Winiecki

27

이것을 확인하는 간단한 기능 :

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

16
한 줄로 줄이려고 return object.constructor === Array하지만 배열에 대해서만 true를 반환한다고 확신합니까?
mpen

12
모든 부울 표현식으로이를 수행 할 수 있습니다. 내가 볼 때 나를 미치게합니다 if(x) return true; else return false:-) 거꾸로하더라도 표현을 부정해야합니다.
mpen

3
이것이 getElementsByTagName에 대해 true를 리턴하지 않는 이유는 해당 함수의 결과가 실제로 HTMLCollection이며 배열이 아니기 때문입니다.
Yuval A.

6
객체가 정의되지 않았거나 null 인 경우 잘못 실패합니다.
존 헨켈

1
@JohnHenckel 내 답변보기 stackoverflow.com/a/29400289/34806 한 줄에 모두 귀하의 우려와 첫 번째 의견을 모두
반영

17

MDN은 다음 같이 말합니다 .

Array.isArray 또는 Object.prototype.toString.call 을 사용 하여 일반 객체와 배열을 구별하십시오.

이처럼 :

  • Object.prototype.toString.call(arr) === '[object Array]'또는

  • Array.isArray(arr)


17

이 질문에 대한 한 가지 해결책이 있습니다.

x instanceof Array

여기서 x는 변수이며 x가 배열이면 true를 반환하고 그렇지 않으면 false를 반환합니다.


훨씬 더 깨끗하고 안전한 미래! 이것 또는 typeof비교.
ChristoKiwi 2016 년

이것은 상당한 양의 브라우저 지원을받는 것입니까? 나는 그것을 좋아한다.
Dan Zuzevich

1
불행히도 "x"가 배열 과 같은 객체{} 이면 구문 오류가 발생 하기 때문에 try / catch가 없으면 실제로 유용하지 않습니다 .
abalter

15

변수의 유형이 배열인지 여부를 확인할 수 있습니다.

var myArray=[];

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

1
몇몇 사람들은 이미 언급했습니다 instanceof. 몇 가지 이상한 시나리오에서는 실패한다고 생각합니다.
mpen

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}
Bergi

JSON.parse(someDataFromElsewhere).items.isArray데이터에 따라 true를 반환하고 코드를 손상시킬 수 있습니다.
Roy Tinker

12

이것은 의견을 고려 하여이 답변 을 개선하려는 시도입니다 .

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

if / else를 제거하고 배열이 null이거나 정의되지 않았을 가능성을 설명합니다.


ES5
TechTurtle


11

오류 확인뿐만 아니라 두 가지 대체 방법으로 jsperf 바이올린 을 업데이트했습니다 .

'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/>");

변수가 정의되지 않은 값을 사용하는 경우이 두 가지 방법은 작동하지 않지만 값이 있는지 확실하면 작동합니다. 값이 배열 또는 단일 값인지 여부를 염두에두고 성능을 확인하는 것과 관련하여 두 번째 방법은 유효한 빠른 방법처럼 보입니다. Chrome의 'instanceof'보다 약간 빠르며 Internet Explorer, Opera 및 Safari (내 컴퓨터)의 두 번째 가장 좋은 방법보다 두 배 빠릅니다.


9

나는 사람들이 일종의 원시 자바 스크립트 접근법을 찾고 있다는 것을 알고 있습니다. 그러나 덜 생각하고 싶다면 여기를보십시오 : http://underscorejs.org/#isArray

_.isArray(object) 

object가 Array 인 경우에 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넘어서 작동 하지 않는다는 것입니다.하지만 사용 사례에서는 이것이 문제가되지 않습니다.


적어도 우분투 64 비트의 FF30에서는 더 이상 성능면에서 더 나을 것입니다
test30

2
wat = {array_: true}사물에 빠지다 .
Bergi

@ Bergi : 예, 분명합니다. 당신이 설정한다면 obj.array_ = true, 당신은 단지 자신을 속이는 것 입니다.
namuol

@namuol : 반드시 나 자신을 속일 필요는 없습니다. 종종 충분한 개체가 사전으로 사용됩니다. cache검색 문자열을 속성 키로 사용하는 검색 결과를 기억 하는 객체를 생각하십시오 . 사용자가 검색하면 array_어떻게됩니까? 그 때문에 객체가 배열이됩니까? 그냥 버그 일뿐입니다.
Bergi

@namuol : 또한이 방법을 사용하려면 모든 관련 당사자 (사용 된 라이브러리 포함)가 .array_배열 태그 지정에 사용되는 것에 동의해야 합니다. 실제로는 그렇지 않습니다 .array. 무엇이든 의미 할 수 있습니다. 최소한 설명 문자열을 사용하고 임의의 사용에 대한 부적합성을 표시해야 .__isArray = true합니다 ( 예 : with) .
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

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

@mpen Object.getPrototypeOf(yourvariable)Array 객체의 프로토 타입을 반환합니다. 그리고 코드는 가장 빠르고 안전합니다.
STEEL

1
붙여 넣기 가 쉽습니다. pastebin.com/MP8d5bCE 또한 "가장 빠른"클레임을 백업하기위한 성능 테스트가 있습니까?
mpen

4

이 함수에 전달 될 수있는 두 종류의 값만 문자열 또는 문자열 배열이면 간단하게 유지 typeof하고 문자열 가능성을 확인하십시오.

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

예.이 시나리오에서는 효과가 있지만 일반적으로는 그렇지 않습니다. 어쨌든 varargs를 사용하여 끝났습니다. :)
mpen

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

가장 짧은 버전을 검색하려면 여기까지 내가 얻은 것입니다.

가능한 모든 조합을 항상 감지하는 완벽한 기능은 없습니다. 마술 도구를 기대하는 것보다 도구의 모든 능력과 한계를 아는 것이 좋습니다.


1
내 약간의 파생 A.map !== undefined 그러나 그래, 그것은 원숭이 패처의 세계에서 미끄러운 길일 수 있었다;)
dmi3y

참고 : iFrame에서 작동하지 않습니다 ( stackoverflow.com/questions/460256/… )
WiredPrairie

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있는 Array 메서드를 사용할 수 있습니다 :

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 배열의 가장 오래된 방법 중 하나 인 것 같습니다 (IE 5.5조차도 잘 알고 있습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.