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