Was ist die beste de-facto standardmäßige browserübergreifende Methode, um festzustellen, ob eine Variable in JavaScript ein Array ist oder nicht?
Beim Durchsuchen des Webs gibt es eine Reihe verschiedener Vorschläge, von denen einige gut und einige ungültig sind.
Das Folgende ist beispielsweise ein grundlegender Ansatz:
function isArray(obj) {
return (obj && obj.length);
}
Beachten Sie jedoch, was passiert, wenn das Array leer ist oder obj tatsächlich kein Array ist, sondern eine Längeneigenschaft usw. implementiert.
Welche Implementierung ist die beste, um tatsächlich zu arbeiten, browserübergreifend zu sein und dennoch effizient zu arbeiten?
javascript
arrays
stpe
quelle
quelle
Antworten:
Die Typprüfung von Objekten in JS erfolgt über
instanceof
, dhDies funktioniert nicht, wenn das Objekt über Frame-Grenzen hinweg übergeben wird, da jeder Frame ein eigenes
Array
Objekt hat. Sie können dies umgehen, indem Sie die interne [[Klasse]] - Eigenschaft des Objekts überprüfen . Verwenden Sie dazuObject.prototype.toString()
(dies funktioniert garantiert mit ECMA-262):Beide Methoden funktionieren nur für tatsächliche Arrays und nicht für Array-ähnliche Objekte wie die
arguments
Objekt- oder Knotenlisten. Da alle Array-ähnlichen Objekte eine numerischelength
Eigenschaft haben müssen, würde ich Folgendes überprüfen:Bitte beachten Sie, dass Zeichenfolgen diese Prüfung bestehen, was zu Problemen führen kann, da der IE den Zugriff auf die Zeichen einer Zeichenfolge nach Index nicht zulässt. Daher möchten Sie möglicherweise zu ändern
typeof obj !== 'undefined'
,typeof obj === 'object'
um'object'
Grundelemente und Hostobjekte mit Typen auszuschließen, die sich von insgesamt unterscheiden. Dadurch werden weiterhin Zeichenfolgenobjekte passieren, die manuell ausgeschlossen werden müssten.In den meisten Fällen möchten Sie tatsächlich wissen, ob Sie über numerische Indizes über das Objekt iterieren können. Daher ist es möglicherweise eine gute Idee, zu überprüfen, ob das Objekt
0
stattdessen eine Eigenschaft mit dem Namen hat. Dies kann über eine der folgenden Überprüfungen erfolgen:Die Umwandlung in ein Objekt ist erforderlich, um für Array-ähnliche Grundelemente (dh Zeichenfolgen) ordnungsgemäß zu funktionieren.
Hier ist der Code für zuverlässige Überprüfungen von JS-Arrays:
und iterierbare (dh nicht leere) Array-ähnliche Objekte:
quelle
hasOwnProperty
Methode, so dass nur das Präfix Ihrerinstanceof
mitobj.hasOwnProperty &&
; Ist dies auch immer noch ein Problem mit IE7? Meine einfachen Tests über den Task-Manager legen nahe, dass der Speicher nach Minimierung des Browsers wiederhergestellt wurde ...Mit der Einführung von ECMAScript 5th Edition können wir am sichersten testen, ob eine Variable ein Array ist: Array.isArray () :
Während die hier akzeptierte Antwort für die meisten Browser über Frames und Fenster hinweg funktioniert , gilt dies nicht für Internet Explorer 7 und niedriger , da ein
Object.prototype.toString
Aufruf eines Arrays aus einem anderen Fenster[object Object]
nicht zurückgegeben wird[object Array]
. IE 9 scheint ebenfalls auf dieses Verhalten zurückgegangen zu sein (siehe aktualisierte Korrektur unten).Wenn Sie eine Lösung suchen, die in allen Browsern funktioniert, können Sie Folgendes verwenden:
Es ist nicht ganz unzerbrechlich, aber es würde nur von jemandem gebrochen, der sich bemüht, es zu brechen. Es umgeht die Probleme in IE7 und niedriger und IE9. Der Fehler ist in IE 10 PP2 weiterhin vorhanden , wurde jedoch möglicherweise vor der Veröffentlichung behoben.
PS, wenn Sie sich über die Lösung nicht sicher sind, empfehle ich Ihnen, sie nach Herzenslust zu testen und / oder den Blog-Beitrag zu lesen. Es gibt andere mögliche Lösungen, wenn Sie sich mit der bedingten Kompilierung nicht wohl fühlen.
quelle
isArray
nicht wahr von Arrays zurück, die in anderen Dokumentmodi erstellt wurden? Ich muss mich darum kümmern, wenn ich etwas Zeit habe, aber ich denke, das Beste, was ich tun kann, ist, einen Fehler in Connect zu melden, damit er in IE 10 behoben werden kann.Crockford hat zwei Antworten auf Seite 106 von "The Good Parts". Der erste überprüft den Konstruktor, gibt jedoch über verschiedene Frames oder Fenster hinweg falsche Negative aus. Hier ist der zweite:
Crockford weist darauf hin, dass diese Version das
arguments
Array als Array identifiziert , obwohl es keine der Array-Methoden enthält.Seine interessante Diskussion des Problems beginnt auf Seite 105.
Es gibt hier eine weitere interessante Diskussion (Post-Good Parts) , die diesen Vorschlag enthält:
Bei all den Diskussionen möchte ich nie wissen, ob etwas ein Array ist oder nicht.
quelle
jQuery implementiert eine isArray-Funktion, die den besten Weg vorschlägt, dies zu tun
(Ausschnitt aus jQuery v1.3.2 - leicht angepasst, um außerhalb des Kontexts einen Sinn zu ergeben)
quelle
Object.prototype.toString()
- das ist weniger wahrscheinlich zu brechenDiebstahl von Guru John Resig und jquery:
quelle
typeof
standardisiert?Was machen Sie mit dem Wert, wenn Sie sich für ein Array entschieden haben?
Wenn Sie beispielsweise die enthaltenen Werte auflisten möchten , wenn sie wie ein Array aussehen, ODER wenn es sich um ein Objekt handelt, das als Hash-Tabelle verwendet wird, erhält der folgende Code das, was Sie möchten (dieser Code stoppt, wenn die Schließfunktion etwas anderes zurückgibt als "undefiniert". Beachten Sie, dass es NICHT über COM-Container oder Aufzählungen iteriert; dies bleibt als Übung für den Leser):
(Hinweis: "o! = Null" -Tests für null und undefiniert)
Anwendungsbeispiele:
quelle
for..in
ist schlecht [tm])for..in
iteriert über aufzählbare Eigenschaften von Objekten; Sie sollten es nicht mit Arrays verwenden, weil: (1) es langsam ist; (2) es wird nicht garantiert, dass die Ordnung erhalten bleibt; (3) Es enthält alle benutzerdefinierten Eigenschaften, die im Objekt oder einem seiner Prototypen festgelegt sind, da ES3 keine Möglichkeit zum Festlegen des DontEnum-Attributs enthält. Es könnte andere Probleme geben, die mir durch den KopfWenn Sie dies in CouchDB (SpiderMonkey) tun, verwenden Sie
Array.isArray(array)
wie
array.constructor === Array
oderarray instanceof Array
nicht funktionieren. Die Verwendungarray.toString() === "[object Array]"
funktioniert, scheint aber im Vergleich ziemlich zwielichtig zu sein.quelle
Wenn Sie browserübergreifend möchten, möchten Sie jQuery.isArray .
quelle
Auf w3school gibt es ein Beispiel, das durchaus Standard sein sollte.
Um zu überprüfen, ob eine Variable ein Array ist, verwenden sie etwas Ähnliches
getestet auf Chrome, Firefox, Safari, ie7
quelle
constructor
für die Typprüfung ist imo zu spröde; Verwenden Sie stattdessen eine der vorgeschlagenen Alternativenconstructor
ist eine reguläre DontEnum-Eigenschaft des Prototypobjekts. Dies ist möglicherweise kein Problem für integrierte Typen, solange niemand etwas Dummes tut, aber für benutzerdefinierte Typen kann dies leicht sein. Mein Rat: Immer verwendeninstanceof
, das die Prototypenkette überprüft und sich nicht auf Eigenschaften stützt, die willkürlich überschrieben werden könnenEine der am besten recherchierten und diskutierten Versionen dieser Funktion finden Sie auf der PHPJS-Website . Sie können auf Pakete verlinken oder direkt zur Funktion gehen . Ich empfehle die Site sehr für gut konstruierte Äquivalente von PHP-Funktionen in JavaScript.
quelle
Nicht genügend Referenz gleich Konstruktoren. Manchmal haben sie unterschiedliche Referenzen des Konstruktors. Also benutze ich String-Darstellungen von ihnen.
quelle
{constructor:{toString:function(){ return "function Array() { [native code] }"; }}}
Ersetzen
Array.isArray(obj)
durchobj.constructor==Array
Proben :
Array('44','55').constructor==Array
return true (IE8 / Chrome)'55'.constructor==Array
return false (IE8 / Chrome)quelle