In den MDN-Dokumenten: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
Es for...of
wird beschrieben, dass das Konstrukt über "iterierbare" Objekte iterieren kann. Aber gibt es eine gute Möglichkeit zu entscheiden, ob ein Objekt iterierbar ist?
Ich habe versucht, gemeinsame Eigenschaften für Arrays, Iteratoren und Generatoren zu finden, konnte dies jedoch nicht.
Gibt for ... of
es eine saubere Möglichkeit, einen Try-Block auszuführen und nach Typfehlern zu suchen?
javascript
Simonzack
quelle
quelle
iterator()
Methode hat . Da es sich jedoch um einen Entwurf handelt, kann nur eine Überprüfung implemenatationsabhängig sein. Welche Umgebung verwenden Sie?Antworten:
Der richtige Weg, um die Iterierbarkeit zu überprüfen, ist wie folgt:
Warum dies funktioniert (iterierbares Protokoll im Detail): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Ich gehe davon aus, dass wir uns in der ES6-Denkweise befinden.
Seien Sie auch nicht überrascht, dass diese Funktion zurückgegeben wird,
true
wennobj
es sich um eine Zeichenfolge handelt, da Zeichenfolgen über ihre Zeichen iterieren.quelle
Symbol.iterator in Object(obj)
.return typeof obj[Symbol.iterator] === 'function'
? "Um iterierbar zu sein, muss ein Objekt die @@ iterator-Methode implementieren" - es gibt die Methode antypeof Object(obj)[Symbol.iterator] === 'function'
in allen Fällen funktionieren?Warum so ausführlich?
quelle
Readability > Cleverness
kehrt immer zurücktrue
.Readability > Cleverness
, hilft es niemandem , die Variableobject
zu verkürzeno
. 2. Eine leere Zeichenfolge''
ist iterierbar und muss daher zurückgegeben werdentrue
.!= null
Die einfachste Lösung ist tatsächlich folgende:
Object
wird alles, was kein Objekt ist, in ein Objekt einschließen, sodass derin
Bediener auch dann arbeiten kann, wenn der ursprüngliche Wert kein Objekt ist.null
undundefined
werden in leere Objekte umgewandelt, sodass keine Erkennung von Kantenfällen erforderlich ist, und Zeichenfolgen werden in iterierbare Zeichenfolgenobjekte eingeschlossen.quelle
Symbol.iterator
.Object
ist für diese Art der Prüfung verschwenderisch.Object
Funktion implementiert ist, aber sie erstellt nur dann ein neues Objekt, wennvalue
es noch kein Objekt ist. Ich würde erwarten, dass die Kombination vonin
undObject(...)
etwas ist, das Browser-Engines im Gegensatz zu beispielsweise leicht optimieren könnenvalue !== undefined && value !== null && value[Symbol.iterator] && true
. Außerdem ist es sehr gut lesbar, was mir wichtig ist.Achten Sie als Nebenbemerkung auf die Definition von iterable . Wenn Sie aus anderen Sprachen kommen, würden Sie erwarten, dass etwas, mit dem Sie beispielsweise eine
for
Schleife durchlaufen können, iterierbar ist . Ich fürchte, das ist hier nicht der Fall, wo iterable etwas bedeutet, das das Iterationsprotokoll implementiert .Zur Verdeutlichung kehren alle obigen Beispiele
false
zu diesem Objekt zurück,{a: 1, b: 2}
da dieses Objekt das Iterationsprotokoll nicht implementiert. Sie werden also nicht in der Lage sein, mit einemfor...of
ABER darüber zu iterieren, aber Sie können es immer noch mit einemfor...in
.Wenn Sie also schmerzhafte Fehler vermeiden möchten, machen Sie Ihren Code spezifischer, indem Sie Ihre Methode wie folgt umbenennen:
quelle
undefined
?object !== null
in Ihrer Antwort getan haben, aber Sie tun dies,object != null
damit esundefined
in diesem speziellen Fall nicht bricht . Ich habe meine Antwort entsprechend aktualisiert.hasIterationProtocol('')
muss zurückkehrentrue
! Wie wäre es, wenn Sie Ihren Code entfernen und einfach den iterierbaren Erklärungsabschnitt verlassen, der das einzige ist, was Ihrer Antwort einen echten Mehrwert / etwas Neues hinzufügt.true
, indem ich einen Teil der alten Antwort entfernte, habe ich beide Funktionen zusammengeführt und den strengen Vergleich vergessen. Jetzt habe ich die ursprüngliche Antwort zurückgesetzt, die gut funktioniert hat.Object(...)
, einen schönen Fang zu verwenden. In diesem Fall ist die Nullprüfung jedoch nicht erforderlich.Heutzutage, wie bereits erwähnt, um zu testen, ob
obj
es iterierbar ist, tun Sie es einfachHistorische Antwort (nicht mehr gültig)
Das
for..of
Konstrukt ist Teil des ECMASCript 6th Edition Language Specification Draft. Es könnte sich also vor der endgültigen Version ändern.In diesem Entwurf müssen iterierbare Objekte die Funktion
iterator
als Eigenschaft haben.Sie können überprüfen, ob ein Objekt wie folgt iterierbar ist:
quelle
Bei asynchronen Iteratoren sollten Sie nach 'Symbol.asyncIterator' anstelle von 'Symbol.iterator' suchen:
quelle
Wenn Sie tatsächlich überprüfen möchten, ob eine Variable ein Objekt (
{key: value}
) oder ein Array ([value, value]
) ist, können Sie Folgendes tun:quelle