ECMAScript 6类属性下划线前缀

我所见过的类模式很像这样:

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'))执行输出:

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

console.log(JSON.stringify(new Foo('x', 'y', 'z')))执行输出:

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

这给了我强调前缀字段,我没有瞄准,我怎么能得到的字段没有下划线前缀,但有getter和setter触发instance.prop交互。

你可以添加一个toJSON方法来调整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)); 

输出: "{"x":"x","y":"y","z":"z"}"

如果你的问题真的只是下划线,那么你可以尝试使用一个更类似于C#的属性的命名约定,其中get / set方法使用PascalCase,但成员variables使用camelCase,如下所示:

 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; } } 

最终,由于ECMAScript 6中的对象是如何工作的,所以没有办法将成员variables和get / set方法命名为100%相同。 事实上,这就是为什么使用下划线格式如此常见。 下划线告诉任何人查看该属性是“私人”的代码。 在ECMAScript 6中,私有成员的概念并不存在。

如果您想跳过下划线属性,请将它们定义为不可枚举:

 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'))) 

正如你所说,你想避免在每个类中使用toJSON (但我也认为使用toJSON是“正确”的事情)。

Javascript让你做怪异的事情,但至less你可以在封闭的函数范围内控制它。

我猜这个正则expression式可能会被改进,但是我只是想展示这个想法,不是很漂亮,而是应该起作用。

 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)); 

输出:

 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' }