我见过的类模式几乎就是这样:
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"}
这给了我下划线前缀字段,我不是针对那个,我如何让字段没有下划线前缀,然而,由instance.prop
交互触发了getter和setter。
答案 0 :(得分:11)
您可以添加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"}"
答案 1 :(得分:5)
如果您的问题确实只是下划线,那么您可以尝试使用更类似于C#的属性的命名约定,其中get / set方法使用PascalCase,但成员变量使用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中如何工作,因此无法使成员变量和名为100%的get / set方法相同。事实上,这就是为什么使用下划线格式是如此常见。下划线告诉任何人查看该属性的目的是" private"。在ECMAScript 6中,私人成员的概念并不存在。
答案 2 :(得分:2)
如果要跳过下划线属性,请将它们定义为不可枚举:
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')))
您还可以考虑符号而不是下划线属性:
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')))
答案 3 :(得分:0)
正如您所说,您希望避免在每个课程中使用toJSON
(但我也认为使用toJSON
是“正确”的事情)。
Javascript让你做一些奇怪的事情,但至少你可以在一个封闭的函数范围内控制它。
我认为正则表达式可以改进,但我只想展示这个想法,不是很漂亮但应该有用。
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' }