2016-11-03 1 views
5

Die Klassen Muster Ich habe so ziemlich kommt gesehen um so etwas wie folgt aus:ECMAScript 6 Klasse Eigenschaften unterstreichen Präfix

class Foo { 
    constructor(x, y, z) { 
     this._x = x; 
     this._y = y; 
     this._z = z; 
    } 

    get x() { 
     return this._x; 
    } 
    set x(value) { 
     //I acctually do some stuff here 
     this._x = value; 
    } 

    get y() { 
     return this._y; 
    } 
    set y(value) { 
     //I acctually do some stuff here 
     this._y = value; 
    } 

    get z() { 
     return this._z; 
    } 
    set z(value) { 
     //I acctually do some stuff here 
     this._z = value; 
    } 
} 

console.log(new Foo('x', 'y', 'z')) Ausführung Ausgabe:

Foo { _x: 'x', _y: 'y', _z: 'z' } 

console.log(JSON.stringify(new Foo('x', 'y', 'z'))) Ausführung Ausgabe:

{"_x":"x","_y":"y","_z":"z"} 

Welche gibt mir unterstrichen Präfixfelder und IW Wie kann ich dafür sorgen, dass die Felder kein Unterstrich-Präfix haben und Getter und Setter durch die Interaktion instance.prop ausgelöst werden.

+0

Ich würde sagen, auf das Entfernen ** _ ** hinter den Variablen? wie 'Konstruktor (x, y, z) { this.x = x; this.y = y; dies.z = z; } ' –

+1

Ja, in diesem Beispiel gibt es keinen Vorteil gegenüber nur die Eigenschaften direkt zuweisen und überspringen die Getter. – loganfsmyth

+0

@loganfsmyth Entschuldigung für das schlechte Beispiel, aber ich benutze wirklich benutzerdefinierte Setter für Eigenschaften in meiner 'realen Welt Anwendung', bearbeiten mein Schnipsel für besseres Verständnis. – vcorrea

Antwort

8

Sie können eine toJSON Methode fügen Sie die Ausgabe von JSON.stringify

class Foo { 
    constructor(x, y, z) { 
     this._x = x; 
     this._y = y; 
     this._z = z; 
    } 

    get x() { 
     return this._x; 
    } 
    set x(value) { 
     this._x = value; 
    } 

    get y() { 
     return this._y; 
    } 
    set y(value) { 
     this._y = value; 
    } 

    get z() { 
     return this._z; 
    } 
    set z(value) { 
     this._z = value; 
    } 

    toJSON() { 
     return { 
     x: this._x, 
     y: this._y, 
     z: this._z 
     }; 
    } 
} 

var foo = new Foo('x', 'y', 'z'); 
console.log(JSON.stringify(foo)); 

Ausgänge anzupassen: "{"x":"x","y":"y","z":"z"}"

+0

Ich sah dieses in ein paar Beispielen, aber ich würde es in jeder Verwendung meiner Klassen verwenden müssen, also ich vermeide es, aber danke für die Referenz! – vcorrea

4

Wenn Ihr Problem wirklich ist nur die Unterstreichungen, versuchen Sie könnten dann eine Namenskonvention ähnlicher C# 's Eigenschaften mit denen die get/set Methoden Pascal verwenden, aber die Elementvariablen verwenden camelcase, etwa so:

class Foo { 
    constructor(x, y, z) { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
    } 

    get X() { 
     return this.x; 
    } 
    set X(value) { 
     this.x = value; 
    } 

    get Y() { 
     return this.y; 
    } 
    set Y(value) { 
     this.y = value; 
    } 

    get Z() { 
     return this.z; 
    } 
    set Z(value) { 
     this.z = value; 
    } 
} 

Aufgrund der Funktionsweise von Objekten in ECMAScript 6 gibt es keine Möglichkeit, sowohl die Elementvariable als auch die get/set-Methoden 100% gleich zu nennen. Aus diesem Grund ist die Verwendung des Unterstrichformats so üblich. Der Unterstrich sagt jedem, der den Code betrachtet, dass die Eigenschaft "privat" sein soll. In ECMAScript 6 existiert das Konzept der privaten Mitglieder nicht wirklich.

+0

Obwohl Ihre Syntax möglicherweise nicht die richtige ist, ist Ihre Antwort von großer Bedeutung, denn dies 'Letztendlich, aufgrund der Funktionsweise von Objekten in ECMAScript 6, gibt es keine Möglichkeit, sowohl die Membervariable als auch die Methoden get/set mit 100 zu versehen Ich bin so erleichtert, jetzt kann ich erleichtert sein und weitermachen, mit einer der vielen Möglichkeiten, die ihr hier präsentiert. Vielen Dank! – vcorrea

3

Wenn Sie die Unterstreichungs Eigenschaften überspringen wollen, definieren sie als nicht-zählbare:

class Foo { 
 
    constructor(x, y, z) { 
 
    this._x = x; 
 
    this._y = y; 
 
    this._z = z; 
 
    Object.defineProperties(this, { 
 
     _x: {enumerable: false}, 
 
     _y: {enumerable: false}, 
 
     _z: {enumerable: false} 
 
    }); 
 
    } 
 
    get x() { return this._x; } 
 
    set x(value) { this._x = value; } 
 
    get y() { return this._y; } 
 
    set y(value) { this._y = value; } 
 
    get z() { return this._z; } 
 
    set z(value) { this._z = value; } 
 
} 
 
console.log(JSON.stringify(new Foo('x', 'y', 'z')))

Sie können auch Symbole anstelle von unterstrichenen Eigenschaften betrachten:

class Foo { 
 
    constructor(x, y, z) { 
 
    this[Foo.x] = x; 
 
    this[Foo.y] = y; 
 
    this[Foo.z] = z; 
 
    } 
 
    get x() { return this[Foo.x]; } 
 
    set x(value) { this[Foo.x] = value; } 
 
    get y() { return this[Foo.y]; } 
 
    set y(value) { this[Foo.y] = value; } 
 
    get z() { return this[Foo.z]; } 
 
    set z(value) { this[Foo.z] = value; } 
 
} 
 
Foo.x = Symbol('x'); 
 
Foo.y = Symbol('y'); 
 
Foo.z = Symbol('z'); 
 
console.log(JSON.stringify(new Foo('x', 'y', 'z')))

+0

beide Snippets haben leere Objekte zurückgegeben D: sogar Upvoted Sie, Bruder, wie konntest du? hahahaha – vcorrea

+2

Sie sind nicht leer. Sie haben nur keine eigene aufzählbare String-Eigenschaft. – Oriol

0

Wie Sie sagten, Sie (aber ich denke auch toJSON verwendet, ist die „richtige“ mit toJSON in jeder Klasse vermeiden wollten etwas zu tun).

Javascript lässt Sie seltsame Dinge tun, aber zumindest können Sie es in einem beiliegenden Funktionsumfang steuern.

Ich denke, die Regex könnte verfeinert werden, aber ich wollte nur die Idee zeigen, nicht schön, aber sollte funktionieren.

class Foo { 
    constructor(x, y, z) { 
    this._x = x; 
    this._y = y; 
    this._z = z; 
    } 

    get x() { 
    return this._x; 
    } 
    set x(value) { 
    //I acctually do some stuff here 
    this._x = value; 
    } 

    get y() { 
    return this._y; 
    } 
    set y(value) { 
    //I acctually do some stuff here 
    this._y = value; 
    } 

    get z() { 
    return this._z; 
    } 
    set z(value) { 
    //I acctually do some stuff here 
    this._z = value; 
    } 
} 

var originalJSON = JSON; 

var foo = new Foo('x', 'y', 'z'); 

(function() { 

    var JSON = { 
    stringify: function (obj) { 
     var json = originalJSON.stringify(obj); 
     return json.replace(/"_+(\w+)":/g, '"$1":'); 
    }, 
    parse: function(str) { 
     return originalJSON.parse(str.replace(/"(\w+)":/g, '"_$1":')); 
    } 
    }; 

    console.log('Weird hack'); 

    var r = JSON.stringify(foo);  
    console.log('stringify'); 
    console.log(r); 

    console.log('parse'); 
    console.log(JSON.parse(r)); 
}).call(); 

console.log('\nBack to normal'); 

var r = JSON.stringify(foo); 
console.log('stringify'); 
console.log(r); 

console.log('parse'); 
console.log(JSON.parse(r)); 

Ausgang:

Weird hack 
stringify 
{"x":"x","y":"y","z":"z"} 
parse 
{ _x: 'x', _y: 'y', _z: 'z' } 
Back to normal 
stringify 
{"_x":"x","_y":"y","_z":"z"} 
parse 
{ _x: 'x', _y: 'y', _z: 'z' } 
Verwandte Themen