Cum verifici dacă o variabilă este o matrice în JavaScript? [duplicat]

Aș dori să verific dacă o variabilă este fie o matrice, fie o singură valoare în JavaScript.

Am gasit o posibila solutie...

if (variable.constructor == Array)...

Este acesta cel mai bun mod în care se poate face acest lucru?


person Andy McCluggage    schedule 20.04.2009    source sursă
comment
Verificarea ca un obiect să fie o matrice are câteva avertismente specifice... Răspunsul lui Peter este singurul pe care ar trebui să-l folosiți.   -  person aleemb    schedule 20.04.2009
comment
@Andy Se pare că răspunsul meu nu este cel mai bun. Poate ar trebui să selectați un alt răspuns ca fiind acceptat?   -  person Peter Smit    schedule 07.08.2011
comment
Bun punct Peter. Nu mi-am dat seama că răspunsul tău a primit astfel de comentarii. Cred că am început de mult să folosesc funcția JQuery.isArray atunci când verific matrice și, în mod interesant, este implementat diferit față de orice alt răspuns dat aici. Am marcat răspunsul popular ca fiind corect.   -  person Andy McCluggage    schedule 08.08.2011
comment
Îmi pare rău că este greșit. M-am uitat puțin mai profund și (începând cu versiunea 1.6.2) JQuery încă scrie verificări folosind comparații sub forma.... toString.call(obj) === [object Array]   -  person Andy McCluggage    schedule 08.08.2011
comment
Pentru suport IE8, aș face acest lucru if ('push' in variable.__proto__), cel mai rapid și poate cel mai bun mod de a verifica dacă unele var sunt matrice.   -  person thednp    schedule 06.07.2015
comment
jsben.ch/#/QgYAV - un etalon al celor mai comune moduri   -  person EscapeNetscape    schedule 24.10.2016
comment
stackoverflow.com/questions/4775722/check -dacă-obiectul-este-matrice/   -  person shinobi    schedule 30.04.2017
comment
Această întrebare a fost pusă înainte... NU, acea întrebare a fost pusă DUPĂ aceasta   -  person Dexygen    schedule 12.11.2017
comment
Ei bine, din nou, acesta este StackOverflow   -  person Peppa    schedule 27.07.2020


Răspunsuri (23)


Există mai multe moduri de a verifica dacă o variabilă este o matrice sau nu. Cea mai bună soluție este cea pe care ați ales-o.

variable.constructor === Array

Aceasta este cea mai rapidă metodă de pe Chrome și, cel mai probabil, pentru toate celelalte browsere. Toate tablourile sunt obiecte, așa că verificarea proprietății constructorului este un proces rapid pentru motoarele JavaScript.

Dacă întâmpinați probleme cu a afla dacă o proprietate a obiectelor este o matrice, trebuie mai întâi să verificați dacă proprietatea este acolo.

variable.prop && variable.prop.constructor === Array

Alte moduri sunt:

Array.isArray(variable)

Actualizare 23 mai 2019 folosind Chrome 75, strigă lui @AnduAndrici pentru că m-a pus să revin cu întrebarea lui Aceasta din urmă este, după părerea mea, cea mai urâtă și este una dintre cele mai lente cel mai rapid. Rulează cu aproximativ 1/5 din viteza ca primul exemplu. Acest tip este cu aproximativ 2-5% mai lent, dar este destul de greu de spus. Solid de folosit! Destul de impresionat de rezultat. Array.prototype, este de fapt o matrice. puteți citi mai multe despre el aici https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

variable instanceof Array

Această metodă rulează aproximativ 1/3 din viteza ca prim exemplu. Încă destul de solid, arată mai curat, dacă ești despre cod frumos și nu atât de performanță. Rețineți că verificarea numerelor nu funcționează, deoarece variable instanceof Number returnează întotdeauna false. Actualizare: instanceof acum atinge 2/3 din viteza!

Deci încă o actualizare

Object.prototype.toString.call(variable) === '[object Array]';

Acest tip este cel mai lent pentru a încerca să verifice un Array. Cu toate acestea, acesta este un magazin unic pentru orice tip pe care îl căutați. Cu toate acestea, deoarece căutați o matrice, utilizați cea mai rapidă metodă de mai sus.

De asemenea, am făcut un test: http://jsperf.com/instanceof-array-vs-array-isarray/35 Așa că distrează-te puțin și verifică-l.

Notă: @EscapeNetscape a creat un alt test, deoarece jsperf.com este oprit. http://jsben.ch/#/QgYAV Am vrut să mă asigur că link-ul original rămâne oricând jsperf revine online.

person jemiloii    schedule 29.10.2014
comment
Pentru a extinde răspunsul dat un alt test jsperf aici folosind testarea caracteristicilor (. push && .pop), care este cel mai rapid și acceptat în toate browserele (chiar și în cele vechi). Problema este că poate un obiect are proprietăți „push” și „pop” fără a fi o matrice. De asemenea, rețineți că atunci când testați dacă este o matrice cu un obiect creat (sau trecut) dintr-un alt cadru, majoritatea testelor vor eșua (deoarece Matricea din fereastra dată este diferită de Matricea în fereastra cadru). De asemenea, există o captură dacă o matrice este construită printr-un nou Array sau literal ca [..] - person Nikos M.; 15.12.2014
comment
Interesant, va trebui să mai fac un test de browser. Chrome 38 pe centos 7 are push && pop cu 10% mai rapid decât constructorul, cu toate acestea, Chrome 39 pe Windows 8 are constructorul ca cel mai rapid, fără o comparație apropiată, deoarece constructorul rulează cu 70% mai rapid decât push && pop. Voi aștepta să vină încă un test, mulțumesc! - person jemiloii; 17.12.2014
comment
Rețineți că, dacă nu sunteți sigur dacă variabila este definită sau dacă ar putea fi nulă, asigurați-vă că efectuați mai întâi acele verificări, deoarece acestea sunt valorile/obiectele comune care nu au un constructor. - person Michael Scott Cuthbert; 12.01.2015
comment
Mă concentram doar pe porțiunea de matrice. Puteți avea cu ușurință variable && variable.constructor === Array pentru a vă asigura că variabila nu este nulă sau nedefinită. - person jemiloii; 12.01.2015
comment
Metode suplimentare: !!~variable.constructor.toString().indexOf('Array()'), variable.constructor.toString() == Array().constructor.toString() (probabil va fi puțin lentă) și Object.prototype.toString.call(variable) == '[object Array]' - person Ismael Miguel; 26.03.2015
comment
variable.constructor este mai rapid doar pentru verificarea matricelor reale. Când verificați obiecte aleatorii (și în lumea reală, acesta va fi cazul, deoarece acesta este motivul pentru care utilizați această funcție) este mai rapid să utilizați instanceof. jsperf.com/check-if-variable-is-array - person Dinu Sorin; 16.03.2016
comment
Folosind Chrome 50.0.2657.0 pe Centos 7, constructorul este încă mai rapid pentru mine. De asemenea, constructorul poate fi folosit pe orice, cu excepția undefined și null. Puteți face pur și simplu variable && variable.constructor. De asemenea, rețineți că 5 instanceof Number nu funcționează conform așteptărilor. În cazul în care arată prototipul, numerele nu au un prototip, cu excepția cazului în care setați unul. Numerele au constructori. - person jemiloii; 16.03.2016
comment
Ca o altă notă ciudată, ` Object.prototype.toString.call(1) === '[Numărul obiectului]';` este un lucru. Javascript este ciudat, așa că Numbers are prototipuri. Doar instanceof nu le folosește. Ceea ce este ciudat pentru că, este singurul scop, potrivit MDN... - person jemiloii; 16.03.2016
comment
NOTĂ: „variable.constructor === Array” va arunca EXCEPȚIE dacă variabila este nulă, dar „variable instanceof Array” nu! - person GorvGoyl; 05.10.2016
comment
dacă te uiți, am dat un exemplu de variable && variable.constructor === Array - person jemiloii; 05.10.2016
comment
Array.isArray(variable) nici măcar nu a funcționat pentru mine. Primul s-a descurcat excelent! - person awe; 20.09.2017
comment
@awe pe ce browser folosești asta? - person jemiloii; 20.09.2017
comment
Conform JSPerf pe care l-ați postat, Array.isArray este cel mai rapid, nu cel mai lent - person Ferrybig; 25.09.2017
comment
in ce browser si versiune esti? Pentru mine, chrome/firefox, pe care l-am testat rapid, constructorul este încă cel mai rapid, cu toate acestea, a existat o îmbunătățire vizibilă a matricelor doar cu șiruri. Matricele numai șiruri sunt foarte rapide. Voi face mai multe teste. - person jemiloii; 25.09.2017
comment
Începând cu Chrome 59, isArray() pare să fie semnificativ mai rapid, atât de mult încât nu văd niciun motiv să nu folosesc isArray() în toate situațiile. - person Hedley Smith; 10.10.2017
comment
Întrebarea inițială nu a menționat performanța. Acele micro-optimizări vor fi nesemnificative pentru aproape toate cazurile de utilizare - person Drenai; 15.02.2018
comment
Unii oameni le place să ofere informații suplimentare în loc de strictul minim :) - person jemiloii; 18.02.2018
comment
Toate benchmark-urile dvs. sunt greșite - atât pentru că V8 (Chrome) a schimbat compilatoarele JIT, cât și pentru că benchmark-urile dvs. nu sunt relevante. Vă recomand să consultați blogul lui mraleph despre performanță și jsperf în special. JSPerf este ca și cum IC-urile nu ar exista și morfismul unei funcții nu este relevant pentru compilator, în timp ce, în practică, caracteristicile de performanță sunt foarte diferite în funcție de ceea ce poate dovedi motorul. - person Benjamin Gruenbaum; 06.07.2018
comment
Și anume, V8 poate trueline value="nofollow" dacă analiza tipului dovedește că valoarea este o matrice. Acest lucru este irelevant, deoarece instanceof este optimizat pe aceeași cale. În mod amuzant, comparația .constructor este mai lentă. Întregul punct al lui isArray este oricum între tărâmuri (matrice trecute între cadre și contexte). - person Benjamin Gruenbaum; 06.07.2018
comment
este variable.constructor === Array în continuare răspunsul acceptat ca fiind cel mai rapid/cel mai performant? sau variable instanceof Array sau Array.isArray(variable) au devenit mai viabile? -- întrebând, deoarece răspunsurile/comentariile sunt destul de vechi în anumite locuri. Foarte apreciat :) - person Andu Andrici; 21.05.2019
comment
Rulați testele pentru a vedea, durează doar un moment. - person jemiloii; 23.05.2019
comment
@AnduAndrici Da, a existat o actualizare bună pentru Array.isArray() pe Chrome. A doua cea mai rapidă opțiune acum. Solid! - person jemiloii; 23.05.2019
comment
Aș dori să secundez întrebarea lui @AnduAndrici pentru că nu mai este clar din răspuns care soluție de aici este cea mai eficientă. - person Sebastian Gaweda; 17.07.2019
comment
este clar @SebastianGaweda, citește răspunsul. variable.constructor === Array Dacă nu mai era cazul, l-aș fi actualizat și aș fi oferit un motiv pentru care am actualizat-o. - person jemiloii; 31.07.2019
comment
@jemiloii Nu sunt de acord că este clar. Actualizările dvs. spun că instanceof rulează cu 2/3 din viteza răspunsului inițial. Asta înseamnă mai repede? Mai lent? Există o oarecare ambiguitate în formulare, deși, desigur, contextul paragrafului pare să indice mai lent. Am rulat câteva benchmark-uri proprii modificând codul din jsben.ch/QgYAV, dar acele rezultate sugerau că instanceof a fost cel mai rapid . Într-o notă similară, jsben.ch/QgYAV se leagă acum la un benchmark gol. - person Sebastian Gaweda; 31.07.2019
comment
Răspuns grozav. Mulțumesc. - person Anjana Silva; 11.12.2019
comment
atât de multe editări fac răspunsul tău imposibil de citit. De aceea votez negativ... - person Clint Eastwood; 27.01.2020
comment
Toate bune, îmi place să văd cum se actualizează JavaScript de-a lungul anilor. - person jemiloii; 28.01.2020
comment
Dacă vrei să-ți editezi răspunsul, te rog să-l faci mai lizibil pentru cei care nu l-au citit înainte. - person AtilioA; 11.06.2020

De asemenea, ai putea folosi:

if (value instanceof Array) {
  alert('value is Array!');
} else {
  alert('Not an array');
}

Aceasta mi se pare o soluție destul de elegantă, dar pentru fiecare a lui.

Editați | ×:

Începând cu ES5 există acum și:

Array.isArray(value);

Dar acest lucru se va rupe pe browserele mai vechi, cu excepția cazului în care utilizați polyfills (în principiu... IE8 sau similar).

person Brett Bender    schedule 20.04.2009
comment
Vă sugerez să insistați să rămâneți cu acest operator de instanță dacă nu lucrați cu mai multe cadre. Acesta este modul corect de verificare a tipului de obiect. - person BYK; 20.04.2009
comment
Singurul caz în care acest lucru ar eșua este dacă ați încerca să testați o matrice sau un obiect începând cu Array instanceof Object == true. - person Pierre; 29.11.2012
comment
Dacă utilizați jQuery pentru a transmite elemente cu find('code') sau ceva similar, ați dori să verificați variabila cu variable instanceof Object, deoarece nu este o instanță a unui Array. - person tuck; 01.05.2013
comment
Pentru a consolida punctul lui @BYK, aceasta funcționează numai cu obiecte din același cadru. Nu vă bazați pe asta dacă lucrați cu mai multe cadre! - person Cory Klein; 25.09.2013
comment
Nu funcționează în unele cazuri: Array.prototype instanceof Array; // false (ar trebui să fie adevărat); de asemenea ({ __proto__ : Array.prototype }) instanceof Array; // true (ar trebui să fie fals) - person vortexwolf; 04.11.2013
comment
Nu sunt bine versat în elementele interne JS - tipul unui prototip ar trebui să fie același cu tipul obiectului? - person Brett Bender; 04.11.2013
comment
@BrettBender Dacă sunteți încă activ, ați putea să vă actualizați răspunsul pentru a reflecta faptul că, începând cu ES5, avem Array.isArray? - person Nobbynob Littlun; 22.05.2014
comment
@AndrewK vezi Răspunsul lui Fela Winkelmolen, care are metoda Array.isArray. În ceea ce privește acest răspuns, probabil că nu este o idee grozavă să transformați un răspuns într-un răspuns diferit prin editare. - person muffin; 25.08.2014
comment
Sau dacă nu vă pasă de browserele vechi, puteți utiliza Array.isArray(arr) - person Dominic; 13.10.2014
comment
Acest lucru este frumos, dar utilizați variable.constructor === Array, de departe cea mai rapidă metodă din javascript. jsperf.com/instanceof-array-vs-array-isarray - person jemiloii; 29.10.2014
comment
@muffin: de ce este o idee bună să lăsăm răspunsul să rămână depășit cu cinci ani? După cum știți, mulți utilizatori nu vor citi comentariile de sub răspuns (atât de mult pe cât ne-am dori), darămite că unele dintre aceste comentarii sunt ascunse sub Afișați mai multe. - person Dan Dascalescu; 04.12.2014
comment
@DanDascalescu Ai dreptate ca nu e bine sa tii ingropata informatiile valoroase. Dar cred că este nepotrivit să modifici răspunsul cuiva până în punctul în care acesta nu mai rămâne același răspuns în esență. Poate că adăugarea unei linii de notificare/fYI editată în răspunsul cel mai votat ar fi utilă într-un mod care să nu trădeze integritatea răspunsului inițial, dar dacă acesta este remediul indicat, sistemul ar trebui să îl încorporeze la același nivel cu votul. și acceptând răspunsuri. Oricum, nu mai citesc meta: nu-mi amintesc care este (sensul meu) consensul cu privire la integritatea răspunsului. - person muffin; 04.12.2014
comment
Acest lucru este corect, deoarece se va descurca dacă valoarea este nedefinită sau nulă. - person James Nurse; 12.08.2015

Există mai multe soluții cu propriile lor ciudatenii. Această pagină oferă o prezentare generală bună . O soluție posibilă este:

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}
person Peter Smit    schedule 20.04.2009
comment
Dacă citiți cu atenție, se spune că această metodă este necesară atunci când lucrați cu documente cu mai multe cadre, ceea ce nu este recomandat. Această metodă poate afecta cu ușurință o mică modificare a funcției toString. - person BYK; 20.04.2009
comment
Prin urmare, linkul este dat, astfel încât Brett să le poată verifica și să vadă în ce caz funcția lui trebuie să funcționeze - person Peter Smit; 20.04.2009
comment
Vezi răspunsul meu mai jos. Recomand drumul lui Peter Smit. - person Brian; 29.06.2012
comment
Această metodă este recomandată de Mozilla . - person Hank; 28.05.2015

Am observat că cineva a menționat jQuery, dar nu știam că există o funcție isArray(). Se pare că a fost adăugat în versiunea 1.3.

jQuery îl implementează așa cum sugerează Peter:

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

După ce am pus deja multă încredere în jQuery (în special în tehnicile lor pentru compatibilitatea între browsere), fie voi face upgrade la versiunea 1.3 și voi folosi funcția lor (cu condiția ca actualizarea să nu cauzeze prea multe probleme), fie voi folosi această metodă sugerată direct în cod.

Multumesc mult pentru sugestii.

person Andy McCluggage    schedule 20.04.2009
comment
Consultați acest articol pentru o buna discutie pe tema. Concluzia este să folosiți această soluție. - person Nick G.; 12.03.2014
comment
Acest lucru îmi dă eroarea SCRIPT65535 în IE10. - person polm23; 27.05.2014

În browserele moderne (și în unele browsere vechi), puteți face

Array.isArray(obj)

(Supportat de Chrome 5, Firefox 4.0, IE 9, Opera 10.5 și Safari 5)

Dacă aveți nevoie să acceptați versiuni mai vechi de IE, puteți utiliza es5-shim pentru a polifill Array .isArray; sau adăugați următoarele

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

Dacă utilizați jQuery, puteți folosi jQuery.isArray(obj) sau $.isArray(obj). Dacă folosești caracterul de subliniere, poți folosi _.isArray(obj)

Dacă nu aveți nevoie să detectați matricele create în cadre diferite, puteți utiliza și instanceof

obj instanceof Array

Notă: cuvântul cheie arguments care poate fi folosit pentru a accesa argumentul unei funcții nu este un Array, chiar dacă (de obicei) se comportă ca unul:

var func = function() {
  console.log(arguments)        // [1, 2, 3]
  console.log(arguments.length) // 3
  console.log(Array.isArray(arguments)) // false !!!
  console.log(arguments.slice)  // undefined (Array.prototype methods not available)
  console.log([3,4,5].slice)    // function slice() { [native code] } 
}
func(1, 2, 3)

person Fela    schedule 08.01.2014
comment
Aceasta este probabil cea mai bună abordare modernă. L-am văzut împreună cu polyfill pe MDN, așa că înseamnă că Mozilla are încredere în el developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person John; 12.04.2014
comment
Nu îți lipsește prototype acolo? Se pare că ar trebui să fie Object.prototype.toString.call. - person Brock; 20.11.2014

Aceasta este o întrebare veche, dar având aceeași problemă, am găsit o soluție foarte elegantă pe care vreau să o împărtășesc.

Adăugarea unui prototip la Array îl face foarte simplu

Array.prototype.isArray = true;

Acum, odată, dacă aveți un obiect pe care doriți să îl testați pentru a vedea dacă este o matrice, tot ce aveți nevoie este să verificați noua proprietate

var box = doSomething();

if (box.isArray) {
    // do something
}

isArray este disponibil numai dacă este o matrice

person Ibu    schedule 24.10.2011
comment
asta mi se pare atat de misto! asta ar putea fi nativ. btw funcționează chiar și atunci când o matrice a fost creată înainte de prototipare? - person Vitim.us; 12.11.2011
comment
@Vitimtk Un prototip acționează ca o rezervă pentru obiectul real, așa că ar trebui să funcționeze chiar dacă matricea în cauză exista deja. Nu va funcționa înainte ca linia sursă să fie procesată, desigur. - person Markus Bruckner; 28.12.2011
comment
Presupunând că nimeni nu face Object.prototype.isArray = true;! :( - person ErikE; 30.09.2012
comment
Rețineți că în ES5 Array.isArray este o metodă (de exemplu, Array.isArray([1,2,3]) === true), așa că @ErikE nu era un troll. Aș evita să urmăresc acest răspuns, deoarece va sparge codul în unele browsere moderne. - person JaredMcAteer; 11.07.2013
comment
@JaredMcAteer exemplul tău este corect. Cu toate acestea, ErikE nu are legătură, Array != [1,2,3] . Deci, puteți face în continuare [1,2,3].isArray === adevărat cu soluția mea - person Ibu; 11.07.2013
comment
@Ibu și tu poți face {}.isArray === true cu soluția mea, care era ideea... - person ErikE; 12.07.2013
comment
Modificarea prototipului de tipuri de date este o practică proastă în opinia mea - person BentOnCoding; 24.09.2014
comment
@BentOnCoding ce zici de Array.prototype["com.my.unique.name"].isArray ;) - person SOFe; 28.12.2018

Prin Crockford:

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (value instanceof Array) {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

Principalul eșec menționat de Crockford este incapacitatea de a determina corect matricele care au fost create într-un context diferit, de exemplu, window. Pagina respectivă are o versiune mult mai sofisticată dacă aceasta este insuficientă.

person Hank Gay    schedule 20.04.2009

Dacă aveți de-a face doar cu EcmaScript 5 și mai sus, atunci puteți utiliza funcția încorporată Array.isArray

e.g.,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false
person JaredMcAteer    schedule 11.07.2013

Personal îmi place sugestia lui Peter: https://stackoverflow.com/a/767499/414784 (pentru ECMAScript 3. Pentru ECMAScript 5, utilizați Array.isArray())

Comentariile la postare indică, totuși, că, dacă toString() este schimbat deloc, acest mod de a verifica o matrice va eșua. Dacă chiar doriți să fiți specific și să vă asigurați că toString() nu a fost schimbat și nu există probleme cu atributul clasei obiectelor ([object Array] este atributul clasei unui obiect care este o matrice), atunci vă recomand să faceți ceva de genul acesta:

//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')
    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    }
    else
    {
        // may want to change return value to something more desirable
        return -1; 
    }
}

Rețineți că în JavaScript The Definitive Guide a 6-a ediție, 7.10, se spune că Array.isArray() este implementat folosind Object.prototype.toString.call() în ECMAScript 5. De asemenea, rețineți că, dacă vă veți face griji cu privire la schimbarea implementării lui toString(), ar trebui să vă faceți griji și cu privire la schimbarea tuturor celorlalte metode încorporate. . De ce să folosiți push()? Cineva o poate schimba! O astfel de abordare este o prostie. Verificarea de mai sus este o soluție oferită celor îngrijorați de toString() schimbare, dar cred că verificarea este inutilă.

person Brian    schedule 03.12.2011
comment
Bun apel la standardul ECMAScript 5. Sigur că nu puteți garanta că browserul îl acceptă, dar aceasta ar trebui să fie prima modalitate de a verifica codul nou. - person styfle; 14.12.2012
comment
Voi începe prin a spune că asta e puțin peste capul meu. Cu toate acestea, un test ca acesta ar fi mai robust?: return Object.prototype.toString.call(o) === Object.prototype.toString.call([]); - person Grant Lindsay; 24.06.2014

Când am postat această întrebare, versiunea de JQuery pe care o foloseam nu includea o funcție isArray. Dacă ar fi avut, probabil că l-aș fi folosit doar având încredere că implementarea respectivă este cea mai bună modalitate independentă de browser de a efectua această verificare specială a tipului.

Deoarece JQuery oferă acum această funcție, aș folosi-o întotdeauna...

$.isArray(obj);

(începând cu versiunea 1.6.2) Este încă implementat folosind comparații pe șiruri în formă

toString.call(obj) === "[object Array]"
person Andy McCluggage    schedule 08.08.2011

M-am gândit să adaug o altă opțiune pentru cei care ar putea folosi deja biblioteca Underscore.js în scriptul lor. Underscore.js are o funcție isArray() (consultați http://underscorejs.org/#isArray).

_.isArray(object) 

Returnează adevărat dacă obiectul este un Array.

person Benjen    schedule 16.03.2012
comment

Am creat un JSFiddle pentru a crea o cronologie orizontală cu CSS și JQuery. Comportamentul cronologiei este, după cum urmează:

Când pagina se încarcă, „timelineSlider” se poziționează întotdeauna sub „Link 1”. Făcând clic pe fiecare element din listă numit „Link”, „TimelineSlider” alunecă spre și sub acel element din listă.

În prezent, funcționează secvenţial atunci când un utilizator face clic pe Link1, Link2, Link3 și apoi Link4. Dar aș dori ca utilizatorul să facă clic pe orice element din listă în orice ordine, iar „timelineSlider” ar trebui fie să alunece la dreapta sau la stânga, fie să nu schimbe poziția, în funcție de poziția anterioară a „timelineSlider”. Cum îmi pot schimba codul JS pentru a face acest lucru?

JSFiddle

$(document).ready(function() {
  $("li").click(function() {
    //Get Initial timelineSlider Margin
    var timelineSliderMargin = parseInt($('.timelineSlider').css('margin-left'));
    //Slide the box to the link clicked (left or right) depending on box position
    $(".timelineSlider").animate({
      'margin-left': (parseInt(calculate(0)) + parseInt($('.timelineSlider').css('margin-left'))) + 'px'
    });
  });
});

function calculate(i) {
  var sum = 0;
  for (var j = 0; j <= i; j++) {
    sum = sum + $("ul li:eq(" + j + ")").outerWidth(true);
  }
  return sum;
}
div.eventsWrapper {
  height: 75px;
  margin-left: 5px;
  position: absolute;
  width: 800px;
}
.eventsConnector {
  background: #0070c0 none repeat scroll 50% 50%;
  height: 3px;
  left: 0;
  margin-left: 185px;
  margin-top: -31px;
  position: absolute;
  transition: transform 0.4s ease 0s;
  width: 512px;
  z-index: -1;
}
#events {
  z-index: 2;
}
#events ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
#events li {
  display: inline-block;
}
#events a {
  display: block;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 5px #0070c0 solid;
  text-transform: uppercase;
  text-decoration: none;
  font-size: 15px;
  text-align: center;
  line-height: 50px;
  margin-left: 125px;
  z-index: 3;
  color: #666666;
  background-color: #0070c0;
}
#events a .event {
  background-color: #ffffff;
  border: 1px solid #ffffff;
  border-radius: 50%;
  color: #666666;
  display: block;
  font-size: 15px;
  height: 48px;
  margin-left: 0;
  margin-top: 0;
  position: relative;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  width: 48px;
  z-index: 4;
}
.timelineSlider {
  width: 110px;
  height: 66px;
  border: 0px;
  margin-left: 95px;
  margin-top: 10px;
  position: absolute;
  z-index: 2;
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="eventsWrapper">
  <div id="events">
    <ul>
      <li>
        <a href="/ro#1">
          <div class="event">LINK1</div>
        </a>
      </li>
      <li>
        <a href="/ro#2">
          <div class="event">LINK2</div>
        </a>
      </li>
      <li>
        <a href="/ro#3">
          <div class="event">LINK3</div>
        </a>
      </li>
      <li>
        <a href="/ro#4">
          <div class="event">LINK4</div>
        </a>
      </li>
    </ul>
  </div>
  <div class="eventsConnector"></div>
  <div class="timelineSlider">Slide this box to the link clicked.</div>
</div>

- person Kris; 24.04.2014
comment
Aceeași funcție este prezentă în Lodash - person Jundiaius; 13.04.2016

Dacă utilizați Angular, puteți utiliza funcția angular.isArray().

var myArray = [];
angular.isArray(myArray); // returns true

var myObj = {};
angular.isArray(myObj); //returns false

http://docs.angularjs.org/api/ng/function/angular.isArray

person joseph.l.hunsaker    schedule 19.03.2014
comment
De asemenea, puteți utiliza browsere nespecifice pentru Angular, dar numai IE9+ și toate browserele standard: ‹pre›‹code› Array.isArray(myArray); // returnează adevăratul Array.isArray(myObj); //returnează false ‹/code› ‹/pre› - person PDA; 17.07.2014

În JavaScript The Good Parts al lui Crockford, există o funcție pentru a verifica dacă argumentul dat este o matrice:

var is_array = function (value) {
    return value &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        typeof value.splice === 'function' &&
        !(value.propertyIsEnumerable('length'));
};

El explica:

În primul rând, întrebăm dacă valoarea este adevărată. Facem acest lucru pentru a respinge valorile nule și alte valori false. În al doilea rând, întrebăm dacă tipul de valoare este „obiect”. Acest lucru va fi valabil pentru obiecte, matrice și (în mod ciudat) nul. În al treilea rând, întrebăm dacă valoarea are o proprietate de lungime care este un număr. Acest lucru va fi întotdeauna valabil pentru matrice, dar de obicei nu pentru obiecte. În al patrulea rând, întrebăm dacă valoarea conține o metodă de îmbinare. Acest lucru va fi valabil din nou pentru toate matricele. În cele din urmă, întrebăm dacă proprietatea lungime este enumerabilă (lungimea va fi produsă de o buclă for in?). Acest lucru va fi fals pentru toate tablourile. Acesta este cel mai fiabil test pentru matrice pe care l-am găsit. Este regretabil că este atât de complicat.

person Yunzhou    schedule 03.12.2013
comment
Și acestea au fost doar părțile bune. Imaginați-vă când va fi publicat JavaScript The Bad Parts... - person FrancescoMM; 30.01.2017

Soluția universală este mai jos:

Object.prototype.toString.call(obj)=='[object Array]'

Pornind de la ECMAScript 5, o soluție formală este:

Array.isArray(arr)

De asemenea, pentru vechile biblioteci JavaScript, puteți găsi soluția de mai jos, deși nu este suficient de precisă:

var is_array = function (value) {
    return value &&
    typeof value === 'object' &&
    typeof value.length === 'number' &&
    typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

Soluțiile sunt de la http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript

person PixelsTech    schedule 11.01.2015

cod referit de la https://github.com/miksago/Evan.js/blob/master/src/evan.js

  var isArray = Array.isArray || function(obj) {
    return !!(obj && obj.concat && obj.unshift && !obj.callee);};
person didxga    schedule 26.05.2011
comment
De ce testați atât concat, cât și unshift, nu ar fi suficient pentru a testa unshift? - person Marco Demaio; 18.02.2014
comment
Cu cât verificăm mai multe metode dacă Array are mutarea, probabil că este într-adevăr o matrice. Alte obiecte ar putea avea concat sau unshift, dar este mai puțin probabil să aibă ambele. - person Kris; 24.04.2014

Am folosit această linie de cod:

if (variable.push) {
   // variable is array, since AMAIK only arrays have push() method.
}
person Saeed Neamati    schedule 06.01.2013
comment
Aceasta nu este deloc o soluție bună. Cu această soluție orice obiect cu o proprietate push care este adevărată va fi considerat un Array. - person teleclimber; 28.04.2014

Pentru cei care codifică golf, un test nesigur cu cele mai puține caractere:

function isArray(a) {
  return a.map;
}

Acesta este folosit în mod obișnuit atunci când parcurgeți/aplatizați o ierarhie:

function golf(a) {
  return a.map?[].concat.apply([],a.map(golf)):a;
}

input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
person Joe Frambach    schedule 24.10.2013

De la w3schools:

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
person Jahid    schedule 29.03.2015

Mi-a plăcut răspunsul lui Brian:

function is_array(o){
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    } else{
        // may want to change return value to something more desirable
        return -1; 
    }
}

dar ai putea sa faci asa:

return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
person zeageorge    schedule 20.04.2013

Am creat acest mic cod, care poate returna tipuri adevărate.

Nu sunt încă sigur de performanță, dar este o încercare de a identifica corect tipul.

https://github.com/valtido/better-typeOf a scris un blog despre asta aici http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof/

funcționează, similar cu tipul actual de.

var user = [1,2,3]
typeOf(user); //[object Array]

Cred că ar putea avea nevoie de un pic de reglare fină și țin cont de lucruri, nu l-am întâlnit sau nu l-am testat corespunzător. deci sunt binevenite îmbunătățiri suplimentare, fie că este vorba de performanță, fie de raportarea incorectă a typeOf.

person Val    schedule 28.07.2014

Cred că folosirea myObj.constructor==Object și myArray.constructor==Matrice este cea mai bună modalitate. Este de aproape 20 de ori mai rapid decât folosirea toString(). Dacă extindeți obiecte cu propriii dvs. constructori și doriți ca acele creații să fie considerate și „obiecte”, atunci acest lucru nu funcționează, dar în rest este mult mai rapid. typeof este la fel de rapid ca metoda constructorului, dar typeof []=='object' returnează adevărat, ceea ce va fi adesea nedorit. http://jsperf.com/constructor-vs-tostring

un lucru de reținut este că null.constructor va arunca o eroare, așa că, dacă s-ar putea să verificați valori nule, va trebui să faceți mai întâi if(testThing!==null){}

person user1585789    schedule 24.08.2014

Deoarece proprietatea .length este specială pentru matrice în javascript, puteți spune pur și simplu

obj.length === +obj.length // true if obj is an array

Underscorejs și alte câteva biblioteci folosesc acest truc scurt și simplu.

person TypingTurtle    schedule 02.03.2014
comment
Vrei să explici cum funcționează? În principal, ce face „+”? - person Andy McCluggage; 03.03.2014
comment
Acest lucru este bun, dar este adevărat și atunci când obiectul este o funcție sau un șir, precum și orice alt obiect cu lungimea proprietății de tipul număr. De ce? Ei bine, operatorul unar + aruncă de fapt o variabilă ca număr. Deci, practic, ei verifică dacă obj.length este un număr. [Object Object] nu are lungimea proprietății este nedefinit, așa că atunci când aruncați nedefinit ca număr, acesta devine NaN, verificarea de mai sus iese ca falsă. Deci returnează adevărat dacă lungimea proprietății obiectului este un număr, care în cazul matricelor, șirurilor și funcțiilor ar fi adevărată. Underscore trebuie să facă mai mult decât asta. - person John; 12.04.2014

Ceva cu care tocmai am venit:

if (item.length) //This is an array else //not an array

person trololol    schedule 12.02.2015
comment
var item = 'this_is_not_an_array'; - person kev; 06.03.2015
comment
Este o soluție proastă! Un șir are și o lungime. - person pmrotule; 09.03.2015
comment
De fapt, un șir este o matrice de caractere, așa că, în esență, funcționează - person Shingala94; 13.03.2015
comment
@PatrickNijhuis - string este un tip primitiv în javascript, în timp ce array este un obiect. În limbajul comun, aveți dreptate - un șir este o matrice de caractere - dar în javascript, această afirmație este greșită. Este o distincție importantă și motivul pentru care acesta este un răspuns prost. - person wahwahwah; 27.03.2015
comment
Nu, o matrice de lungime zero este încă o matrice. - person Dave Burton; 14.08.2016
comment
puteți pune typeof item == 'obiect' și răspunsul poate fi acceptabil - person Abz Rockers; 31.08.2017
comment
mai important: o matrice goală va eșua acest test deoarece 0 este fals - person David Schumann; 26.03.2020