2014-04-22 6 views
5

Typescript: Wie Methode mit Pfeilfunktion in der Basisklasse mit Super-Schlüsselwort in der Kindklasse definiert aufrufen?

Bei
class BaseClass{ 

    count:number=0; 

    public someMethod=():void =>{ 
     this.count++; 
    } 
} 

class ChildClass extends BaseClass{ 
    public someMethod=():void=>{ 
    super.someMethod(); 
    //Do more work here. 
    } 
} 

ich die Fehlermeldung:

nur öffentliche Methoden der Basisklasse sind über das 'super' Schlüsselwort zugänglich.

@Basarat bietet einige Informationen hier, aber das scheint wie ein echter Hack für die Sprache. typescript arrow operator to define a function on prototype

Wie könnte dies unter Beibehaltung der kontextuellen Verwendung von "this" geschehen?

Verwende ich Pfeilfunktionen richtig oder sollten sie wirklich nur dazu benutzt werden, etwas wie einen Rückruf zu deklarieren?

+0

Ich bin sicher, dass Sie bereits wissen ... aber immer noch teilen wollten (daher ein Kommentar: https://www.youtube.com/watch?v=tvocUcbCupA&hd=1) – basarat

+0

Ich versuche zu verstehen, warum Sie wollen auf diese Weise überhaupt eine Pfeilfunktion zu verwenden. Gibt es einen Grund, warum Sie keine normale Methode für den Prototyp verwenden können? – thoughtrepo

+2

Ich bevorzuge es, Klassen zu schreiben, die davon ausgehen, dass 'dies' die Klasse ist, und den Umfang und Kontext mit' call', 'apply' oder einer Pfeilfunktion behandelt, wo der Aufrufcode diesen Kontext ändert. – Fenton

Antwort

4

Pfeil funktioniert ordnungsgemäß oder sollten sie wirklich nur als eine Methode verwendet werden, um etwas wie einen Rückruf zu deklarieren?

Sie sollten wirklich nur für Rückrufe verwendet werden. Wenn Sie eine Klassenhierarchie möchten, verwenden Sie den Prototyp. prototype spart Ihnen auch Speicher.

Erzwungene Fehler: Es gibt nur einen this und es ist die aktuelle Instanz. Wenn Sie this.foo in der Kindklasse überschreiben, gehen die Basisinstanzen this.foo verloren. Bewahren Sie die Basisversion im Konstruktor

class BaseClass{ 

    count:number=0; 

    public someMethod=():void =>{ 
     this.count++; 
    } 
} 

class ChildClass extends BaseClass{ 

    constructor(){  
     super(); 
     var baseSomeMethod = this.someMethod; 
     this.someMethod =()=>{ 
      // implement here 
     } 
    } 

} 
+0

Klasse Eltern { public foo =(): void => { // Sachen } } Klasse Kind sich Eltern { Konstruktor() { Super(); var superFoo = this.foo; this.foo =() => { superFoo(); } } } – humbolight

+0

Ich dachte, es wäre hilfreich, eine Barebones Pfeilfunktion Vererbung Refactor Ihres Codes hinzuzufügen, mit Sprache in Bezug auf Eltern und Super. Für diejenigen, die versuchen, diese Parallele zu zeichnen, ist es vielleicht einfacher, hier zu sehen. – humbolight

1

Ohne Funktion Umsetzung im Prototyp, gibt es keine Möglichkeit für die abgeleitete Klasse zu ‚finden‘ die Basisklassenimplementierung. Sie können es so trennen, dass Sie eine Methode haben für this und eine andere für die Verwendung über super Erhaltung:

class BaseClass { 
    count: number = 0; 

    someMethodImpl() { 
    this.count++; 
    } 

    public someMethod = this.someMethodImpl; 
} 

class ChildClass extends BaseClass { 
    public someMethod =(): void=> { 
    super.someMethodImpl(); 
    //Do more work here. 
    } 
} 
0

möchte einfach mal eine „Antwort“ auf diese Frage aus einer anderen Diskussion hier erfassen: https://typescript.codeplex.com/workitem/2491

Definitiv nicht effizient in Bezug auf Speicher- oder Verarbeitungsaufwand, aber es beantwortet die Frage.

class Base { 
    x = 0; 
    constructor() { 
     for (var p in this) 
      if (!Object.prototype.hasOwnProperty.call(this, p) && typeof this[p] == 'function') { 
       var method = this[p]; 
       this[p] =() => { method.apply(this, arguments); }; 
       // (make a prototype method bound to the instance) 
      } 
    } 
} 

class A extends Base { 
    doSomething(value) { alert("A: " + value + "/x == " + this.x); } 
} 

class B extends A { 
    doSomething(value) { alert("B: " + value + "/x == " + this.x); super.doSomething(value); } 
} 

var b = new B(); 
var callback = b.doSomething; 
callback("Cool!"); 
5

Aus Gründen der Argumentation, übernehmen Sie

  • sind die Fett-Pfeil-Syntax, da die Methoden von UI Ereignisse oder Rückrufe ausgelöst werden (in Click-Ereignisse meinem Fall Knockout)
  • Vererbung erforderlich, um Redundanz im Antwortcode der Benutzeroberfläche (oder des Rückrufs) zu eliminieren.

Eine minimal hackish (wenn nicht elegant) Antwort ist Ihre Funktion in zwei Anrufe zu teilen, die die beiden Themen behandelt werden:

Class A { 
    public handleScope =() => { 
     return this.handleInheritance(); 
    } 

    public handleInheritance() { 
     // do work 
    } 
} 

Class B extends A { 
    public handleInheritance() { 
     super.handleInheritance() // super works here 
     // additional work 
    } 
} 

Ich bin die erste, die zugibt, dass Funktionen Verdoppelung ist „hässlich“ , aber IMHO viel weniger hässlich als die anderen Möglichkeiten, die ich gesehen habe.Um bei der Standardisierung der Benennung zu helfen, nenne ich die einzeilige "Scoping" -Funktion den Namen der Basisfunktion (z. B. myFunction) plus "Scoper" (d. H. myFunctionScoper).