Tho*_*hia 19 javascript stringify ecmascript-6 es6-class
我有一个JavaScript ES6类,它具有一个属性集,set并通过get函数进行访问.它也是一个构造函数参数,因此可以使用所述属性实例化该类.
class MyClass {
constructor(property) {
this.property = property
}
set property(prop) {
// Some validation etc.
this._property = prop
}
get property() {
return this._property
}
}
Run Code Online (Sandbox Code Playgroud)
我_property用来逃避使用get/set的JS问题,如果我直接设置它会导致无限循环property.
现在我需要对MyClass的一个实例进行字符串化,以便通过HTTP请求发送它.字符串化的JSON是一个对象,如:
{
//...
_property:
}
Run Code Online (Sandbox Code Playgroud)
我需要保留生成的JSON字符串,property以便我发送给它的服务可以正确解析它.我还需要property保留在构造函数中,因为我需要从服务发送的JSON构造MyClass的实例(它发送property没有的对象_property).
我该如何解决这个问题?如果我只是把它发送到HTTP请求之前截获MyClass的实例,并发生变异_property,以property使用正则表达式?这看起来很难看,但我能够保留当前的代码.
或者,我可以拦截从服务发送到客户端的JSON,并使用完全不同的属性名称实例化MyClass.但是,这意味着服务两侧的类的不同表示.
Ama*_*dan 27
您可以使用toJSON方法来自定义类序列化为JSON的方式:
class MyClass {
constructor(property) {
this.property = property
}
set property(prop) {
// Some validation etc.
this._property = prop
}
get property() {
return this._property
}
toJSON() {
return {
property: this.property
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*sár 12
如果你想避免调用toJson,还有另一种使用可枚举和可写的解决方案:
class MyClass {
constructor(property) {
Object.defineProperties(this, {
_property: {writable: true, enumerable: false},
property: {
get: function () { return this._property; },
set: function (property) { this._property = property; },
enumerable: true
}
});
this.property = property;
}
}
Run Code Online (Sandbox Code Playgroud)
如@Amadan所述,您可以编写自己的toJSON方法。
此外,为了避免每次将属性添加到类时都重新更新方法,可以使用更通用的toJSON实现。
class MyClass {
get prop1() {
return 'hello';
}
get prop2() {
return 'world';
}
toJSON() {
// start with an empty object (see other alternatives below)
const jsonObj = {};
// add all properties
const proto = Object.getPrototypeOf(this);
for (const key of Object.getOwnPropertyNames(proto)) {
const desc = Object.getOwnPropertyDescriptor(proto, key);
const hasGetter = desc && typeof desc.get === 'function';
if (hasGetter) {
jsonObj[key] = desc.get();
}
}
return jsonObj;
}
}
const instance = new MyClass();
const json = JSON.stringify(instance);
console.log(json); // outputs: {"prop1":"hello","prop2":"world"}Run Code Online (Sandbox Code Playgroud)
如果要发出所有属性和所有字段,则可以替换const jsonObj = {};为
const jsonObj = Object.assign({}, this);
Run Code Online (Sandbox Code Playgroud)
另外,如果要发出所有属性和某些特定字段,可以将其替换为
const jsonObj = {
myField: myOtherField
};
Run Code Online (Sandbox Code Playgroud)
我对Alon Bar的脚本进行了一些调整。以下是一个非常适合我的脚本版本。
toJSON() {
const jsonObj = Object.assign({}, this);
const proto = Object.getPrototypeOf(this);
for (const key of Object.getOwnPropertyNames(proto)) {
const desc = Object.getOwnPropertyDescriptor(proto, key);
const hasGetter = desc && typeof desc.get === 'function';
if (hasGetter) {
jsonObj[key] = this[key];
}
}
return jsonObj;
}
Run Code Online (Sandbox Code Playgroud)