programing tip

변수가 배열인지 감지하는 방법

itbloger 2020. 8. 19. 07:49
반응형

변수가 배열인지 감지하는 방법


JavaScript의 변수가 배열인지 여부를 결정하는 데 가장 좋은 사실상의 표준 크로스 브라우저 방법은 무엇입니까?

웹 검색에는 여러 가지 제안이 있으며, 일부는 훌륭하고 일부는 유효하지 않습니다.

예를 들어 다음은 기본적인 접근 방식입니다.

function isArray(obj) {
    return (obj && obj.length);
}

그러나 배열이 비어 있거나 obj가 실제로 배열이 아니지만 길이 속성 등을 구현하면 어떤 일이 발생하는지 확인하십시오.

그렇다면 실제로 작동하고 브라우저를 넘나들며 효율적으로 수행하는 측면에서 가장 좋은 구현은 무엇입니까?


JS에서 객체의 유형 검사는를 통해 수행됩니다 instanceof.

obj instanceof Array

각 프레임에 자체 Array개체 가 있기 때문에 개체가 프레임 경계를 넘어 전달되는 경우에는 작동하지 않습니다 . 개체 의 내부 [[Class]] 속성을 확인하여이 문제를 해결할 수 있습니다 . 그것을 얻으려면 다음을 사용하십시오 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'alltogether을. 이것은 여전히 ​​문자열 객체를 통과시킬 수 있으며, 수동으로 제외해야합니다.

대부분의 경우 실제로 알고 싶은 것은 숫자 인덱스를 통해 객체를 반복 할 수 있는지 여부입니다. 따라서 객체에 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;
    }
}

ECMAScript 5th Edition이 출시되면서 변수가 배열 인 경우 가장 확실한 테스트 방법 인 Array.isArray ()가 제공됩니다 .

Array.isArray([]); // true

여기에 허용 대답은 대부분의 브라우저에 대한 프레임과 창문을 통해 작동하지만, 그것은 낮은 인터넷 익스플로러 7이 켜지지 않고 있기 때문에, Object.prototype.toString반환하는 다른 창에서라는 배열에 [object Object]하지 [object Array]. IE 9도이 동작으로 회귀 한 것으로 보입니다 (아래 업데이트 된 수정 사항 참조).

모든 브라우저에서 작동하는 솔루션을 원한다면 다음을 사용할 수 있습니다.

(function () {
    var toString = Object.prototype.toString,
        strArray = Array.toString(),
        jscript  = /*@cc_on @_jscript_version @*/ +0;

    // jscript will be 0 for browsers other than IE
    if (!jscript) {
        Array.isArray = Array.isArray || function (obj) {
            return toString.call(obj) == "[object Array]";
        }
    }
    else {
        Array.isArray = function (obj) {
            return "constructor" in obj && String(obj.constructor) == strArray;
        }
    }
})();

완전히 깨지지는 않지만 누군가가 깨뜨 리려고 애쓰는 사람에 의해서만 깨질 것입니다. IE7 이하 및 IE9의 문제를 해결합니다. 이 버그는 IE 10 PP2에 여전히 존재 하지만 출시 전에 수정 될 수 있습니다.

PS, if you're unsure about the solution then I recommend you test it to your hearts content and/or read the blog post. There are other potential solutions there if you're uncomfortable using conditional compilation.


Crockford has two answers on page 106 of "The Good Parts." The first one checks the constructor, but will give false negatives across different frames or windows. Here's the second:

if (my_value && typeof my_value === 'object' &&
        typeof my_value.length === 'number' &&
        !(my_value.propertyIsEnumerable('length')) {
    // my_value is truly an array!
}

Crockford points out that this version will identify the arguments array as an array, even though it doesn't have any of the array methods.

His interesting discussion of the problem begins on page 105.

There is further interesting discussion (post-Good Parts) here which includes this proposal:

var isArray = function (o) {
    return (o instanceof Array) ||
        (Object.prototype.toString.apply(o) === '[object Array]');
};

All the discussion makes me never want to know whether or not something is an array.


jQuery implements an isArray function, which suggests the best way to do this is

function isArray( obj ) {
    return toString.call(obj) === "[object Array]";
}

(snippet taken from jQuery v1.3.2 - slightly adjusted to make sense out of context)


Stealing from the guru John Resig and jquery:

function isArray(array) {
    if ( toString.call(array) === "[object Array]") {
        return true;
    } else if ( typeof array.length === "number" ) {
        return true;
    }
    return false;
}

What are you going to do with the value once you decide it is an array?

For example, if you intend to enumerate the contained values if it looks like an array OR if it is an object being used as a hash-table, then the following code gets what you want (this code stops when the closure function returns anything other than "undefined". Note that it does NOT iterate over COM containers or enumerations; that's left as an exercise for the reader):

function iteratei( o, closure )
{
    if( o != null && o.hasOwnProperty )
    {
        for( var ix in seq )
        {
            var ret = closure.call( this, ix, o[ix] );
            if( undefined !== ret )
                return ret;
        }
    }
    return undefined;
}

(Note: "o != null" tests for both null & undefined)

Examples of use:

// Find first element who's value equals "what" in an array
var b = iteratei( ["who", "what", "when" "where"],
    function( ix, v )
    {
        return v == "what" ? true : undefined;
    });

// Iterate over only this objects' properties, not the prototypes'
function iterateiOwnProperties( o, closure )
{
    return iteratei( o, function(ix,v)
    {
        if( o.hasOwnProperty(ix) )
        {
            return closure.call( this, ix, o[ix] );
        }
    })
}

If you are doing this in CouchDB (SpiderMonkey) then use

Array.isArray(array)

as array.constructor === Array or array instanceof Array do not work. Using array.toString() === "[object Array]" does work but seems pretty dodgy in comparison.


If you want cross-browser, you want jQuery.isArray.


On w3school there is an example that should be quite standard.

To check if a variable is an array they use something similar to this

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

tested on Chrome, Firefox, Safari, ie7


One of the best researched and discussed versions of this function can be found on the PHPJS site. You can link to packages or you can go to the function directly. I highly recommend the site for well constructed equivalents of PHP functions in JavaScript.


Not enough reference equal of constructors. Sometime they have different references of constructor. So I use string representations of them.

function isArray(o) {
    return o.constructor.toString() === [].constructor.toString();
}

Replace Array.isArray(obj) by obj.constructor==Array

samples :

Array('44','55').constructor==Array return true (IE8 / Chrome)

'55'.constructor==Array return false (IE8 / Chrome)

참고URL : https://stackoverflow.com/questions/1058427/how-to-detect-if-a-variable-is-an-array

반응형