Ich bin auf der Suche nach einer endgültigen Antwort darauf, warum das Erweitern von eingebauten Prototypen in der JS-Entwickler-Community so stark kritisiert wird. Ich verwende das Prototype JS-Framework seit einiger Zeit und finde es [1,2,3].each(doStuff)
viel eleganter als $.each([1,2,3], doStuff)
. Ich weiß, dass es "Namespace-Verschmutzung" verursacht, aber ich verstehe immer noch nicht, warum es als eine schlechte Sache angesehen wird. Gibt es auch einen echten Leistungsabfall, der mit der Erweiterung von eingebauten Prototypen verbunden ist? Vielen Dank!
15
for(var ... in ...)
Schleifen durcheinander geraten, da auch Prototypfunktionen übergeben werden.Antworten:
Ich empfehle Ihnen, diesen Artikel zu lesen, der meiner Meinung nach ziemlich gut erklärt, warum das Erweitern von Objekten eine schlechte Idee ist, auch im Hinblick auf Prototype.
In Summe:
Fehlende Spezifikation
Hostobjekte haben keine Regeln
Möglichkeit von Kollisionen
Leistungsaufwand
IE DOM ist ein Durcheinander
Bonus: Browser-Fehler
quelle
Ein weiterer Grund ist die Lesbarkeit / Wartbarkeit des Codes. Wenn ein anderer Entwickler (insbesondere ein Neuling) meinen Code liest und sieht
[0, 1, 2].foo(...)
, dass er möglicherweise nicht weiß, was die foo-Methode ist oder wo er Dokumentation / Quelle dafür findet. Ist foo eine Erweiterung der Sprache, die von prototype.js oder einer anderen verwendeten Bibliothek oder einem anderen Teil meines Codes in einer anderen Datei hinzugefügt wurde, oder handelt es sich um eine native JavaScript-Methode, die sie nicht kannten? Sie müssen danach suchen und finden es möglicherweise nicht sofort (oder bei Konflikten finden sie möglicherweise nicht das richtige).Beim jQuery-Ansatz
$.foo(...)
macht der Namespace der foo-Methode deutlich, wo sich ihre Definition / Dokumentation befindet, wenn Sie nicht wissen, was sie tut.quelle
Hier ist das grundlegende Problem: Was passiert, wenn Sie über zwei Tools verfügen, die Prototypen auf inkompatible Weise erweitern, oder die allgemein als Methoden bezeichneten Methoden so erweitern, dass sie unterschiedliche Ergebnisse liefern (dies ist ein spezielles Problem
for...in
in JavaScript), wodurch Code entsteht, der darauf angewiesen ist auf ihr normales Verhalten zu brechen?Grundsätzlich sind es die gleichen Probleme, die Sie haben, wenn Sie globale Variablen missbrauchen. An sich passiert vielleicht nichts Schlimmes. Aber es macht Sie ärgerlich, wenn plötzlich zwei scheinbar voneinander getrennte Code-Teile aufeinander treten (und es ist schwierig, Fehler zu beheben, wenn dies passiert).
Natürlich ist prototype.js ziemlich bekannt, und die meisten Tools arbeiten mit der Funktionsweise. Ebenso bin ich sicher, dass es Fälle gibt, in denen die Erweiterung von Basisprototypen das Richtige ist. Aber Vorsicht ist geboten.
quelle
Ich bin mir nicht sicher, ob dies wirklich noch ein Problem ist, aber meiner Erfahrung nach war es mit früheren Versionen von Internet Explorer manchmal nicht möglich, bestimmte eingebaute Typen zu erweitern.
quelle
Hier gibt es zwei verschiedene Probleme. Die erste betrifft die allgemeine Erweiterung von integrierten Prototypen und die andere betrifft die Erweiterung von DOM-Prototypen. Die Argumente gegen die Erweiterung von eingebauten Prototypen:
Array.prototype
oderObject.prototype
kann Folgewirkungen haben, z. B. das Hinzufügen der in einerfor...in
Schleife aufgezählten ErweiterungsmethodenFür die Erweiterung von DOM-Prototypen gilt weiterhin das oben genannte mögliche Konfliktargument. Darüber hinaus sind DOM-Knoten Hostobjekte und unterliegen daher keiner der normalen Regeln für native JavaScript-Objekte. Sie können im Wesentlichen das tun, was sie möchten und sind nicht verpflichtet, sinnvolle Prototypobjekte bereitzustellen oder sogar zusätzliche ("expando") Eigenschaften zuzulassen. Verschiedene weirdnesses über Eigenschaften auf verschiedenen DOM - Objekten IE insbesondere macht von seinem Recht, die Bereitstellung keine Prototypen für DOM vor IE - Objekten 9 und mit (auch wenn Sie sind in der Regel OK Festlegen der Eigenschaften von Elementen, sofern nichts von Satz
document.expando
zufalse
.)quelle