__proto__, Wann wird es vorbei sein? Alternativen?
Mozilla behauptet, es entfernen würde, __proto__ eine Weile zurück (~2008) und es ist immer noch im browser. Ist es noch zu veraltet? Es funktioniert in Opera (Safari glaube ich) und Chrom sowie. Ich brauche nicht zu kümmern, d.h. ich würde gerne weiterhin verwenden.
Aber ich will nicht, dass mein code, um aufhören zu arbeiten, eines Tages, so weiter zu meiner Frage:
__proto__ ermöglicht Toten die einfache Vererbung:
a.__proto__ = {'a':'test'}
Ist es trotzdem kann ich replizieren diese in einer standardkonformen Weise? Ich weiß, es ist funktionale Vererbung, das ist hässlich, und es über-erschwert die Tatsache, dass ich nur wollen, um einen Prototypen zu erstellen-Kette. Nur Frage mich, ob alle Zauberer haben das Problem gelöst.
Dank
- Es scheint, dass
__proto__
können standardisiert werden, die in der nächsten ECMAScript. Kann nicht absolut sicher sein, bis abgeschlossen. wiki.ecmascript.org/doku.php?id=harmony:specification_drafts ...zumindest ist es, auf die verwiesen wird in dem aktuellen Entwurf in Anhang B, Zusätzliche Funktionen für Web-Browsern.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hinweis: Es als eine schlechte Praxis, um den Wert zu ändern von
__proto__
. Dabei wird dringend abgeraten von Brendan Eich, der Erfinder von JavaScript, unter anderem. In der Tat die__proto__
Eigenschaft wurde komplett entfernt, von ein paar JavaScript-engines wie Rhino. Wenn Sie wissen wollen warum, dann Lesen Sie die folgenden Kommentar von Brendan Eich.Update: Browser sind nicht zu entfernen, die
__proto__
Eigenschaft. In der Tat, ECMAScript Harmony hat nun standardisiert sowohl die__proto__
- Eigenschaft und diesetPrototypeOf
Funktion. Die__proto__
Eigenschaft wird nur unterstützt, für alte Gründe. Sie sind dringend empfohlen,setPrototypeOf
undgetPrototypeOf
statt__proto__
.Warnung: Obwohl
setPrototypeOf
ist nun ein standard, Sie sind immer noch davon abgeraten es zu benutzen da mutiert der Prototyp eines Objekts unweigerlich tötet Optimierungen und macht den code langsamer. Darüber hinaus ist die Verwendung vonsetPrototypeOf
ist in der Regel ein Indiz für schlechte Qualität code.Brauchen Sie nicht zu kümmern, Ihre vorhandenen code nicht funktioniert einen Tag. Die
__proto__
Eigenschaft ist hier zu bleiben.Nun, für die Frage auf der hand. Wir wollen etwas ähnliches machen, um diese in ein Standard-konformes Weg:
Natürlich kannst du nicht verwenden
Object.create
um dieses Ziel zu erreichen, sind wir da nicht ein neues Objekt erstellen. Wir sind nur versuchen, zu ändern die interne[[proto]]
Eigenschaft des gegebenen Objekts. Das problem ist, dass es nicht möglich ist, ändern Sie die internen[[proto]]
Eigenschaft eines Objekts, wenn es einmal erstellt ist (außer über__proto__
die wir versuchen zu vermeiden).So, um dieses problem zu lösen, schrieb ich eine einfache Funktion (beachten Sie, dass es funktioniert für alle Objekte außer für Funktionen):
So können wir jetzt ändern, den Prototyp jedes Objekt, nachdem es erstellt wurde, wie folgt (beachten Sie, dass wir eigentlich nicht das ändern der internen
[[proto]]
Eigenschaft des Objekts, sondern erzeugen ein neues Objekt mit den gleichen Eigenschaften wie das gegebene Objekt und die erbt von der gegebenen Prototyp):JS:
HTML:
Einfach und effizient (und wir haben nicht mit dem
__proto__
Eigenschaft).__proto__
— es ist eine interne detail, dass einige Implementierungen passieren zu entlarven.__proto__
Eigenschaft wird als standard in die nächste version von JavaScript-Code, @cliffsofinsanity oben dargelegt. Die implementors davon abraten, weil es nicht ein standard noch nicht. Damit es funktioniert möglicherweise nicht in allen JavaScript-engines. Es ist immer eine gute Idee, um zu verstehen, warum eine bestimmte Funktion nicht empfohlen, verwendet werden, anstatt nur zu kritisieren Menschen. Mit der__proto__
Eigenschaft auf das web ist in Ordnung, da alle gängigen Browser unterstützen es. Ich sehe keine Einschränkung der Verwendung es zu speichern, dass es nicht funktioniert in Rhino. Es hat nichts zu tun mit Windows.__proto__
. Ich sage nur, dass du kannst verwenden Sie es heute, ohne sorgen, ob Ihr code funktioniert nicht in der Zukunft. Das ist nur die Hälfte meiner Antwort. Die andere Hälfte befasst sich mit der änderung der internen[[proto]]
eines Objekts ohne Einstellung__proto__
und ich denke, dass allein verdient ein upvote - es ermutigt die Menschen zu denken, außerhalb der box und sicherlich nicht ermutigen, mit__proto__
, und ich bin nicht ein__proto__
evangelist mehr: github.com/javascript/augmenta = setPrototypeOf(a, e)
- siehe den letzten Teil meiner Antwort. Es erstellt eine Kopie des Objekts, das Sie passieren, um es mit dem neuen Prototyp. Sie sollten daher weisen Sie die variablea
auf dem neuen Objekt. Es ist unmöglich, sich zu ändern, den internen[[proto]]
vona
ohne Verwendung__proto__
. Dies ist die nächste beste Sache. Siehe die arbeiten demo: jsfiddle.net/LCWC7__proto__
es ist sicher zu verwenden.setPrototypeOf
"unsicher" war? Btw, es scheint ES6 standardisierteReflect.setPrototypeOf
, während alle Browser unterstützenObject.setPrototypeOf
. Ich sehe weiter verwirrend demnächst 🙂Reflect.setPrototypeOf
aber da es scheint, dass in Bezug auf die reflection-API sehe ich nicht, wie es verursacht keine Verwirrung. Nur die geschickte JavaScript-Programmierer verwenden das mit der reflection-API und würde es keine Schatten der Zweifel in Ihrem Verstand, wenn Sie finden würde, umReflect.setPrototypeOf
.__proto__
und die unsicheresetPrototypeOf
" so Klang, als ob es war sogar weniger "sicher" als__proto__
🙂Ich denke, der eigentliche Punkt, Mozilla machen wollte ist, dass es Sondermaße, so das implementors wäre perfekt in Ihre Rechte, es zu entfernen.
Den cleaner Weg, das zu tun Prototyp-Ketten ist
Object.create
. Das Pendant zu Ihrem code, um ein Objekt zu erstellena
mit dem Prototyp{'a': 'test'}
ist:Gibt es auch shims zu imitieren, um diese Funktion in Browsern, die dies nicht unterstützen, wenn Sie jemals brauchen, um mit zu arbeiten, und das ist ein weiterer Vorteil gegenüber direkt Herumspielen mit
__proto__
.__proto__
.Sehe ich nicht, wie:
Ist einfacher als:
Nun die Einrichtung Eines im letzteren Fall können Sie Ausführlicher, wenn Sie nicht brauchen eine Konstruktor-Funktion, aber
in diesem Fall können Sie automatisieren es genauso einfach:
Gegenüber:
Und wenn Sie benötigen einige Initialisierungs-Logik, wird es wohl am Ende nicht einfacher, nur zu verwenden
der normale Weg, auf dem die Konstruktor-Funktion deklariert werden muss sowieso