ES6-Vererbung: verwendet 'super', um auf die Eigenschaften der Elternklasse zuzugreifen

8

Javascript super Schlüsselwort, wenn ich den Code auf Chrome, Babel, TypeScript, habe ich verschiedene Ergebnisse.

Meine Frage ist, welches Ergebnis korrekt ist? Und welcher Teil der Spezifikation definiert dieses Verhalten?

Der folgende Code:

%Vor%

Die Ergebnisse:

  • Chrome 58.0.3029.110 64 Bit (V8 5.8.283.38)
  • Babel Repl 6.24.2
  • TypeScript 2.3

Links:

justjavac 24.05.2017, 04:53
quelle

3 Antworten

5

Kurze Antwort:

Chrome ist korrekt. Und das liegt an der Unausgewogenheit zwischen get und set.

OrdinarySet ist reciever sensitive, aber OrdinaryGet ist nicht.

So super.x = 3 hat den gleichen Effekt wie this.x = 3 , weil der Empfänger hier this ist. Das Auswerten von super.x , das niemals this erreicht, wird immer undefined erhalten, weil A.prototype kein solches Feld hat.

Weitere Details:

Das super.x ist eine SuperReference . Und die Zuweisung zu SuperReference ruft PutValue (V, W) auf, die ihrerseits super objects aufrufen Interner Slot [[Set]] und schließlich OrdinarySet .

Im einfachen JavaScript entspricht die Anweisung super.x = 3 im Wesentlichen:

OrdinarySet(proto, 'x', 3, this) .

Dabei ist proto das Superobjekt, intern der [[HomeObject]] des Konstruktors %Code%. ColorPoint entspricht proto , wie die ClassDefinitionEvaluation angibt, und sie wird übergeben Konstruieren als Object.create(Point.prototype) .

Sehen wir uns nun an, wie [[HomeObject]] funktioniert. In Schritt 4c und 4d erfordert die Spezifikation, dass der Set-Vorgang am Empfänger OrdinarySet durchgeführt wird, nicht am this -Objekt.

  

Lassen bestehendeDescriptor sein? Empfänger. [GetOwnProperty].

     

Wenn existingDescriptor nicht undefiniert ist,

     

Wenn IsAccessorDescriptor (existingDescriptor) true ist, geben Sie false zurück.

     

Wenn existingDescriptor. [[Writable]] false ist, geben Sie false zurück.

     

Sei valueDesc der PropertyDescriptor {[[Value]]: V}.

     

Zurück? Empfänger. [[DefineOwnProperty]] (P, valueDesc).

Diese Aussage sagt proto bedeutet OrdinarySet(proto, 3, this) .

Andererseits ignoriert this.x = 3 OrdinaryGet . Receiver ist

super.x .

OrdinaryGet(proto, 'x', this) hat überhaupt keine OrdinaryGet in seinen Klauseln ! Also Receiver entspricht super.x , was natürlich Object.create(Point.prototype).x ist.

Als Faustregel gilt: Wenn es Unterschiede zwischen den Übersetzern und Browsern gibt, sind Browser, insbesondere Chrome, in der Regel der ECMAScript-Spezifikation loyaler. Üblicherweise tauschen Transpilers eine gewisse Randfallkorrektheit für die Laufzeit-Effizienz aus.

    
Herrington Darkholme 24.05.2017, 13:54
quelle
0

Eine Programmierregel Garbage in -> Garbage out . Der folgende Code:

%Vor%

Sie erhalten einen schönen TypeScript-Fehler Only public and protected methods can be accessed . Beachten Sie das Wort methods . super sollte nicht für properties verwendet werden. Ungültiger Code sollte nicht ausgeführt werden.

    
basarat 24.05.2017 06:22
quelle
0

Difference Ich sah: -

super hilft dabei, all diesen Teil der oben genannten Klasse zu übernehmen  und wir können das entsprechend ändern "

  1. wir können this.x des Klassenpunktes durch super.x ODER this.x in JAVASCRIPT ändern   Aber wir können keine Änderung in Tyescript mit super.x machen (es wird sich verhalten   der neue objekt der klasse colorPoint) .. diese änderung kann   passiert nur durch this.x

  2. wir können nicht einmal das zweite mal zu super () machen in JAVASCRIPT wird es ein geben   err und wir können die super () in type Skript aufrufen   Dadurch wird die Point-Konstruktorklasse

  3. erneut initialisiert

Typoskript, was ich in TypeScript Spielplatz bemerkt habe, indem ich es ausgeführt habe

%Vor%

Javascript, was ich in der Konsole durch den Befehl node super.js

bemerkt habe %Vor%     
hardy 24.05.2017 06:25
quelle