2017-05-03 1 views
3

Ich habe eine Situation, in der ein Klassenkonstruktor das Ergebnis des Aufrufs einer statischen Methode zurückgibt.Korrekte Weise, auf eine Elementfunktion von einer statischen Methode in einer JavaScript-Klasse zu verweisen

Allerdings muss ich in dieser statischen Methode eine Funktion aufrufen, die eine Memberfunktion sein sollte, aber wenn es eine Memberfunktion ist, ist sie nicht verfügbar.

Gibt es einen guten Weg, dies zu tun?

Dieser Code soll klären helfen:

class Program { 
    constructor (paths) { 
    this.inputs = {} 
    this.program = Program.createProgram(paths) 
    return this.program 
    } 

    static createProgram() { 
     const return_program = {name: test} 
     // async function executes 
     this.modifyProgramName() // This is an error because modifyProgram name is not static on this class 
     return return_program 
} 

modifyProgramName() { 
    // Execute a promise 
    fetch('someresource').then(() => { 
    this.program.name = 'newName' 
    }, 500) 
} 

Hier modifyProgram sollte wirklich nicht static sein, weil die Implikation „Modifizierung“ ist ein Programm, dass es bereits existiert.

Wenn ich jedoch modifyProgram in createProgram aufrufen möchte, die im Wesentlichen der Konstruktor ist, kann ich nicht, weil keine Instanz der Program-Klasse noch existiert.

Gibt es einen guten Weg, dies zu tun?

+0

Warum ist 'createProgram()' statisch? Angenommen, Sie kommen über das aktuelle Problem hinaus, wie würden Sie die oben genannte Klasse verwenden? – nnnnnn

+0

'createProgram' ist statisch, da es im Konstruktor aufgerufen wird, um ein Programm zurückzugeben. Sie könnten es im Konstruktor nicht aufrufen, wenn es nicht statisch wäre. – Startec

+0

Sie sollten immer noch eine Methode vom Konstruktor aufrufen können. Ich werde meine Antwort aktualisieren, um es dir zu zeigen. –

Antwort

1

Versuchen Sie, this an die statische Funktion zu übergeben. Wie folgt aus:

class Program { 
    constructor (paths) { 
    this.inputs = {} 
    this.program = Program.createProgram(paths, this) 
    return this 
    } 

    static createProgram (paths, program) { 
     const return_program = {name: "test"} 
     // async function executes 
     program.modifyProgramName() // This is an error because modifyProgram name is not static on this class 
     return return_program 
    } 
    modifyProgramName() { 
    setTimeout(() => { 
     this.program.name = 'newName' 
    }, 500) 
    } 
} 

Ergebnisse aus der Konsole:

pgm = new Program(["/one"]); 
Program {inputs: Object, program: Object} 
pgm.program.name 
"newName" 

Beachten Sie, dass ich Ihre setTimeout änderte das => Format zu verwenden, so dass this wird derjenige von dem Objekt sein.

Wenn Sie nicht createProgram müssen statisch sein, dann wird diese Arbeit:

class Program { 
    constructor (paths) { 
    this.inputs = {} 
    this.program = this.createProgram(paths) 
    return this 
    } 

    createProgram (paths) { 
     const return_program = {name: "test"} 
     // async function executes 
     this.modifyProgramName() // This is an error because modifyProgram name is not static on this class 
     return return_program 
    } 
    modifyProgramName() { 
    setTimeout(() => { 
     this.program.name = 'newName' 
    }, 500) 
    } 
} 

pgm = new Program(["/one"]); 
Program {inputs: Object, program: Object} 
pgm.program.name 
"newName" 
1

Es ist eine schlechte Idee, etwas anderes zurück als ‚this‘ in einem Konstruktor wie dieses Erbe brechen.

In jedem Fall ist das Problem, dass wenn das SetTimeout eine Funktion mit dem Schlüsselwort function übergeben wird, es im globalen Kontext ausgeführt wird, was bedeutet, dass das Schlüsselwort 'this' auf den globalen Geltungsbereich zeigt. Ein Weg, um damit umzugehen, wäre es, die es6 Fettpfeilfunktionen zu verwenden oder das Schlüsselwort "bind" zu verwenden.

(function() { 
    this.program.name = 'newName'; 
}).bind(this) 

https://jsfiddle.net/uvwt9eqd/1/

+0

Ich bin mir nicht ganz sicher, ob dies die Dinge ändert, aber ich habe 'setTimeout' als einfache Demo benutzt. In Wirklichkeit wird eine Webanfrage gestellt. Frage aktualisiert – Startec

+0

Nein ändert nichts. Verwenden Sie entweder eine Pfeilfunktion, wie @Steve vorgeschlagen hat, oder binden Sie die Funktion – derp

+0

* "In jedem Fall ist das Problem" * - Dies ist nicht das "Problem", es ist ein sekundäres Problem, das nicht auftreten wird, bis der Code geändert wird irgendwie zu erlauben, 'modifyProgramName()' an erster Stelle aufgerufen werden. – nnnnnn

Verwandte Themen