2015-08-17 7 views
5

Ich bin kürzlich auf das Problem der Verwendung von for..in Schleifen auf Arrays in JavaScript gestoßen.JavaScript: Unzählbare Eigenschaften - wann und warum?

Nach den Antworten in this Frage, for..in ist beabsichtigt, die Eigenschaften eines Objekts, einschließlich der vererbten aufzuzählen.

Wenn ja, warum haben wir die Möglichkeit, Eigenschaften mit Object.defineProperty als nicht aufzählbar zu definieren? Geht das nicht gegen die ganze Absicht von for..in? Oder wird es als schlechte Praxis angesehen und sollte vermieden werden?

Auch, warum sollten wir über alle Eigenschaften in einer solchen Weise in erster Linie iterieren (d. H. Mit einer For..in-Schleife)? Wann könnte das nützlich sein?

Und warum nicht alle (Array) Prototypenerweiterungen als nicht aufzählbar definieren und weiterhin for..in mit Arrays verwenden?

Antwort

6

Das Problem ist, dass es nur einen Namespace für Objekteigenschaften gibt (ignorieren die Symbol-Funktion in ES2015 für jetzt). Es gibt einige Objekteigenschaften, die Sie aufzählen wollen, und andere nicht. Die Eigenschaften, die Objektdaten und Beziehungen zu anderen Objekten enthalten, teilen diesen Namespace mit den Namen von Methoden.

Die Schleife for ... in sieht nicht nur die Eigenschaften des Objekts direkt beteiligt, sondern auch die Prototyp-Kette. Das ist wahrscheinlich die wahrscheinlichste Verwendung für nicht-enumerierbare Eigenschaften: Die Methoden, die Sie möglicherweise auf ein Prototypobjekt wahrscheinlich setzen möchten, müssen nicht aufzählbar sein.

Für mich ist der wirkliche Grund, for ... in nicht zu verwenden, wenn Sie durch die numerischen Namen einer Array-Instanz iterieren, dass es keine Garantie gibt, dass Sie die Indizes in einer bestimmten Reihenfolge durchlaufen. Obwohl die meisten Laufzeitsysteme numerische Eigenschaften in der offensichtlichen Reihenfolge zurückgeben, erfordert die Spezifikation für die Sprache absolut nicht, dass dies der Fall ist. Indem Sie einen expliziten numerischen Index in einer einfachen for-Schleife verwenden, steuern Sie dadurch explizit die Iterationsreihenfolge.

Benutzer, die JavaScript-Code für die Verwendung in Kontexten schreiben, in denen anderer Code ausgeführt wird, über den sie keine Kontrolle haben (z. B. werbefinanzierte Websites oder Websites mit vielen Metriktools), wissen dies anhand von integrierten Prototypen nicht mit zufälligem Müll verschmutzt zu werden, ist zutiefst unklug. Mit for ... in wird Ihr Code dem schlechtesten Coder ausgeliefert, der zu diesem Code von Drittanbietern beiträgt.

Moderne Implementierungen haben Object.keys(), die die aufzählbaren "eigenen" Eigenschaftsnamen eines Objekts zurückgibt; das heißt, die Namen der Eigenschaften direkt auf dem Objekt und keine aus der Prototypkette.

+0

Sie sagen also, dass das Erweitern von integrierten Prototypen mit aufzählbaren Eigenschaften eine schlechte Kodierung ist, und in einer Welt voller perfekter Kodierer wäre es vollkommen legitim, sie für Arrays zu verwenden? Wenn ja, was ist zum Beispiel mit prototype.js? Machen sie es nur falsch? –

+0

@JohanHirsch ** Nein **, ich bin ** nicht ** sage, dass 'für ... in' wäre gut mit Arrays zu verwenden. Bitte lesen Sie den dritten Absatz oben noch einmal. Prototype.js war ein ehrgeiziges Projekt, und ich denke, es war zwar ein gutes Experiment, aber es ist ein starker Beweis dafür, dass die Erweiterung von Systemobjekten keine großartige Idee ist. Da die meisten JavaScript-Umgebungen nun nicht aufzählbare Eigenschaften zulassen, wäre Prototype vielleicht weniger ein Problem. (Ich habe sehr gerne mit Prototype gearbeitet, als ich das vor 8 oder 9 Jahren getan habe.) – Pointy

Verwandte Themen