2016-10-30 4 views
1

ich ein benutzerdefinierten Fehler Objekt, das das Error-Objekt erweitert:NodeJS Objekt Vererbung

function GTError(reason, loglevel, meta) { 
    winston.log(loglevel, reason, meta); 
    GTError.super_.apply(this, arguments); 
} 

util.inherits(GTError, Error); 

Ich weiß, dass dies nicht funktioniert, und this question hat Abhilfen dafür. Meine Frage ist nicht, wie man es umgeht, meine Frage ist warum funktioniert es nicht? Warum ruft GTError.super_.apply(this, arguments); (wo GTError.super_ ist Error) die message Eigenschaft der this nicht auf?

enter image description here

können Sie erklären, bitte? Dank

+0

Sie werden den Code für 'util.inherits' zeigen müssen oder ob es aus einer Bibliothek ist, sagen, welche. – JJJ

+0

@JJJ https://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor – robertklep

+0

Was ist 'GTError.super_'? – Joseph

Antwort

1

Meine Frage ist nicht, wie um ihn zu arbeiten, ist meine Frage, warum funktioniert es nicht?

Da die Error Funktion immer eine neue Instanz zurückgibt, auch wenn Sie nicht nennen es mit new; Es ändert nicht das Objekt this bezieht sich auf, wenn Sie es aufrufen. Von the ES5 specification:

Wenn Error als Funktion aufgerufen wird und nicht als ein Konstruktor, erstellt es und initialisiert ein neues Error Objekt. Somit entspricht der Funktionsaufruf Error(…) dem Objekterstellungsausdruck new Error(…) mit den gleichen Argumenten.

Also in Ihrem Code, GTError.super_.apply(this, arguments); (wo GTError.super_ ist Error) ist effektiv ein no-op, weil es schafft und wegwirft ein Error Objekt anstatt machen Error das als this gebene Objekt füllen. In der Tat gibt es keine Möglichkeit (in ES5) Error das durch new in Ihrem Ausdruck erstellte Objekt new GTError aufzufüllen, da Error definiert wurde.

Das TC-39-Komitee hat das in ES2015 behoben, aber nur, wenn Sie die neuen Klassen verwenden (um Abwärtskompatibilität zu gewährleisten).


Ich weiß, Sie sagen, Sie, warum nur wissen wollen, aber für andere: In ES2015 und später können Sie richtig Error über die neuen class Sachen Unterklasse. Diese Syntax wird mindestens in Knoten v4 im strikten Modus und allgemein in Knoten v6 unterstützt. Im Folgenden wird in der jüngsten Version von Chrome oder Firefox arbeiten:

let winston = { 
 
    log: function(...args) { 
 
    console.log("log", ...args); 
 
    } 
 
}; 
 
class GTError extends Error { 
 
    constructor(reason, loglevel, meta) { 
 
     winston.log(loglevel, reason, meta); 
 
     super(reason, loglevel, meta); 
 
    } 
 
} 
 
try { 
 
    throw new GTError("reason", 10, "meta"); 
 
} 
 
catch (e) { 
 
    console.log(e instanceof Error); 
 
    console.log(e instanceof GTError); 
 
    console.log(e.message); 
 
}