Pytanie Sprawdź, czy obiekt jest tablicą?


Próbuję napisać funkcję, która akceptuje listę ciągów lub pojedynczy ciąg znaków. Jeśli jest to ciąg znaków, to chcę go przekonwertować na tablicę za pomocą tylko jednego elementu. Wtedy mogę go przerzucić bez obawy o błąd.

Jak więc sprawdzić, czy zmienna jest tablicą?


Podsumowałem różne rozwiązania poniżej i stworzyłem Test jsperf.


2146
2018-01-23 18:53


pochodzenie


Myślałem, że masz zamiar "sprawdzić, czy obiekt jest tablicą", ale chcesz sprawdzić, czy "obiekt to tablica łańcuchów lub pojedynczy ciąg". Nie wiesz, czy to widzisz? Czy to tylko ja? Myślałem o czymś bardziej podobnym to... czy mi tu brakuje czegoś? - rr1g0
TL; DR - arr.constructor === Array jest najszybszy. - Neta
jsben.ch/#/QgYAV - punkt odniesienia dla najczęstszych sposobów - EscapeNetscape
TL; DR - Array.isArray (arr) od ES5; i $.isArray (arr) w jQuery. - Ondra Žižka
Pamiętaj, że jeśli z jakiegoś powodu nadpiszesz swojego konstruktora za pomocą prototypu arr.constructor === Array test zwróci wartość false. Array.isArray(arr) nadal zwraca wartość true. - ghaschel


Odpowiedzi:


W nowoczesnych przeglądarkach możesz to zrobić

Array.isArray(obj)

(Wspierany przez Chrome 5, Firefox 4.0, IE 9, Opera 10.5 i Safari 5)

W celu zapewnienia kompatybilności wstecznej możesz dodać następujące elementy

# 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]';
  }
};

Jeśli używasz jQuery, możesz użyć jQuery.isArray(obj) lub $.isArray(obj). Jeśli używasz podkreślenia, możesz go użyć _.isArray(obj)

Jeśli nie musisz wykrywać tablic utworzonych w różnych ramkach, możesz po prostu użyć instanceof

obj instanceof Array

319
2018-01-06 18:11



Tutaj jest Bardziej kompletny lista obsługiwanych przeglądarek Array.isArray - lightswitch05
if (typeof Array.isArray === 'undefined') { można zmienić na if(!Array.isArray) { - iMatoria
Tyle ile jest warte Object.prototype.string.call(obj) może zostać sfałszowany, jeśli obiekt ma Symbol.toStringTag na tym. Powiedział, że nie jestem świadomy żadnego środowiska, które wysyła Symbol.toStringTag ale nie Array.isArray więc wydaje się to bezpieczne. - Benjamin Gruenbaum


Metoda podana w standardzie ECMAScript do znalezienia klasy obiektu to użycie toString metoda z Object.prototype.

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

Lub możesz użyć typeof sprawdzić, czy jest to ciąg znaków:

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

Lub jeśli nie zależy Ci na wydajności, możesz po prostu zrobić concat do nowej pustej tablicy.

someVar = [].concat( someVar );

Istnieje również konstruktor, do którego możesz bezpośrednio skierować zapytanie:

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

Sprawdź a dokładne leczenie od @ T.J. Crowder's blog, jak napisano w jego komentarzu poniżej.

Sprawdź to reper aby dowiedzieć się, która metoda działa lepiej: http://jsben.ch/#/QgYAV

Od @Bharath przekonwertuj ciąg do tablicy używając Es6 dla zadanego pytania:

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

przypuszczać:

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']

1866
2018-01-23 18:54



+1 Yup, toString jest jednym ze sposobów, aby przejść. Robię tu trochę podsumowania: blog.niftysnippets.org/2010/09/say-what.html - T.J. Crowder
Jeśli nie chcesz pisać "[Array obiektów]", użyj Object.prototype.toString.call (someVar) === Object.prototype.toString.call ([]) lub skorzystaj z funkcji wygody, aby uzyskać nie chcesz wpisać Object.prototype.toString.call - Pramod
Łał. Metodą concat jest jeden chory szczur. Dałbym +2, ale to nie jest dozwolone - Dark Star1
Używam wanilii Array.isArray, która działa w "nowoczesnych przeglądarkach" (tj. IE9 + i wszystkich innych). A dla starej obsługi przeglądarki użyj podkładki z MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - David Gilbertson
Żyj we współczesnym świecie - Array.isArray(obj) - mcfedr


Najpierw sprawdziłbym, czy twoja implementacja wspiera isArray:

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

Możesz także spróbować użyć instanceof operator

v instanceof Array

1225
2018-01-23 18:55



+1 dla instancji Array. Najprostszy AFAICT - Tom Auger
v instanceof Array zwróci false, jeśli v został utworzony w innej ramce (v jest przykładem thatFrame.contentWindow.Array klasa). - pepkin88
Aby być konkretnym: Array.isArray jest zdefiniowany jako część ECMAScript 5 / JavaScript 1.8.5. - jevon
Naprawdę proste i zadbane rozwiązanie ALE isArray nie jest kompatybilny z niektórymi starszymi przeglądarkami (np. IE7 i IE8). Źródło: kangax.github.io/es5-compat-table/# - Wookie88
Co powiesz na to: if (Array.isArray) zwróci Array.isArray (v); else return v instanceof Array; - lewdev


jQuery oferuje również $.isArray() metoda:

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>


283
2018-04-02 12:15



Jako odniesienie: api.jquery.com/jQuery.isArray - Akseli Palén
Po prostu notatka, jQuery wewnętrznie używa metody toString: Źródło GitHub - Jacob Squires
@JacobSquires to zależy. Właśnie testowałem tutaj, najnowsze jQuery w Chrome - $.isArray === Array.isArray powraca true. - Renan
@Renan: To jest dobra rzecz w używaniu jQuery. Zwykle używa najnowocześniejszej i najlepszej metody, aby to zrobić, i nie musisz wykonywać wszystkich funkcji sprawdzania siebie, aby wiedzieć, co używać. - awe
Ale nikt nie będzie używał jQuery TYLKO DO tej funkcjonalności, prawda? Nie pobrałbym tylko jquery, ponieważ chcę sprawdzić, czy coś jest tablicą: p - Automagisch


Jest to najszybszy spośród wszystkich metod (wszystkie obsługiwane przeglądarki):

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

84
2017-12-06 10:12



Masz rację, to jest najszybsza według testów, które zawarłem w pytaniu. - mpen
Czy są jakieś minusy korzystania z tej metody? Wydaje się to o wiele prostsze i skuteczniejsze niż akceptowana, najwyższa odpowiedź. - David Meza
@shinobi - po prostu ciekawy (i widziałem to często) - dlaczego określasz warunek if (obj && Array === obj.constructor) w przeciwieństwie do if (obj && obj.constructor === Array) ? Czy to zagubienie w tłumaczeniu na angielski, a potem coś kodu? np. anglojęzyczni zwykle pytają "czy obiekt istnieje i czy jego konstruktor pochodzi z klasy tablicowej?", więc przepływ kodu podczas jego odczytu jest bardziej logiczny. czy jest jakiś techniczny powód? - unsynchronized
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();} - unsynchronized
@Shinobi wszystko dobrze. Przypuszczam, że może to być kac z bezpiecznego nawyku - jeśli przypadkowo użyjesz = zamiast ==, nie skompilowałbyś go jako zmiennej nieprzenośnej. - unsynchronized


Array.isArray działa szybko, ale nie jest obsługiwany przez wszystkie wersje przeglądarek. Możesz zrobić wyjątek dla innych i użyć metody uniwersalnej:

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

31
2017-12-10 17:01



Możesz dodać objaśnienie kodu, aby ułatwić zrozumienie dla innych użytkowników, ale poza tym - miło. +1 - Jeff
Musisz zdobyć .toString() metoda z Object.prototype. W tej chwili używasz window.toString(), to nie to samo. - the system
Masz rację. window.toString zrób to samo co Object.prototype.toString tylko w Chrome. - CruorVult
wow ('isArray' in Array). Nigdy wcześniej tego nie widziałem. thks - Ivan Ferrer Villa
isArray wcale nie jest szybki. Jest to najwolniejsza metoda. - jemiloii


Wyobraź sobie, że masz tę tablicę poniżej:

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

JavaScript (nowe i starsze przeglądarki):

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

lub

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

lub

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

następnie nazwij to tak:

isArray(arr);

JavaScript (IE9 +, Ch5 +, FF4 +, Saf5 +, Opera10.5 +)

Array.isArray(arr);

jQuery:

$.isArray(arr);

Kątowy:

angular.isArray(arr);

Podkreślenia i Lodasha:

_.isArray(arr);

29
2017-12-27 13:17





Prosta funkcja, aby to sprawdzić:

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}

20
2017-09-04 17:56



Sprowadziłbym to do jednej linii return object.constructor === Array - ale czy jesteś pewien, że to tylko zwróci true dla tablic? - mpen
Można to zrobić ze wszystkimi wyrażeniami logicznymi. Napędza mnie, kiedy widzę if(x) return true; else return false :-) Nawet jeśli jest cofnięty, powinieneś zanegować wyrażenie. - mpen
Powodem, dla którego nie zwraca to wartości true dla getElementsByTagName, jest fakt, że wynikiem tej funkcji jest faktycznie HTMLCollection, a nie tablica. - Yuval A.
To nie działa źle, jeśli obiekt jest niezdefiniowany lub ma wartość NULL. - John Henckel
@JohnHenckel Zobacz moją odpowiedź stackoverflow.com/a/29400289/34806 bierze pod uwagę zarówno twoje obawy, jak i pierwszy komentarz, wszystko w jednym wierszu - George Jempty


Możesz spróbować tego podejścia: http://web.archive.org/web/20100424091244/http://www.ajaxdr.com/code/javascript-version-of-phps-is_array-function/

EDYTOWAĆ: również, jeśli już używasz JQuery w swoim projekcie, możesz użyć jego funkcji $ .isArray ().


16
2018-01-23 18:56



Miłe znalezisko z trasą jQuery - niewielu z nas naprawdę odkrywa bogactwo swoich rzadziej używanych funkcji! - Dav
+1 Dobre znalezisko! Nie wiedziałem, że istnieje jQuery isArray, to by było przydatne jakiś czas temu - William Isted
W swoim podejściu wszystkie przedmioty, które zawierają własność push będzie tablicą: is_array({push: true});//true - CruorVult


Jak mówi MDN tutaj:

posługiwać się Array.isArray lub Object.prototype.toString.call różnicować   regularne obiekty z tablic

Lubię to:

  • Object.prototype.toString.call(arr) === '[object Array]', lub

  • Array.isArray(arr)


13
2017-09-14 21:02