我希望JSON.stringify也输出geters。我知道它没有显示,因为geters不是“可枚举的”。
我找到了一个解决方案,我正在使用Object.defineProperty来扩展具有可枚举属性的geter,如以下链接所示: Working example with Object.defineProperty in the constractor
我想使用装饰器做同样的事情,但它不起作用,如下面的链接所示: Not working example with Object.defineProperty in the decorator - How can i fix that?
请不要建议我实现toJSON()属性,我知道它可能会有所帮助,但我不想要那个解决方案,我希望它只与装饰器一起工作。
有人可以帮忙吗?
它也适用于 Angular ,因为我需要对formGroup.patchValue也适用于getter。
我用@acdcjunior建议更新了我的例子:this link,希望他能找到我在这里缺少的东西。
答案 0 :(得分:1)
https://developer.amazon.com/docs/fire-tv/audio-video-synchronization.html#section1-2,仅序列化对象自己的可枚举属性。使用该装饰器,您可以将getter添加为原型对象的属性。
24.3.2.3运行时语义:SerializeJSONObject(value)
带参数值的抽象操作SerializeJSONObject 序列化一个对象。它可以访问堆栈,缩进,间隙和 stringify方法的当前调用的PropertyList值。
(...)
- 如果 PropertyList 未定义,则
- 设K PropertyList 。
- 否则,
- 设K为ES6 Spec(值)。
相关点是6
。
如果你问, PropertyList 与EnumerableOwnNames有关,所以它不能成为逃生舱。
使用方法级别装饰器,虽然你说你不想要它,但我能想到的唯一方法是让装饰器添加toJSON
(如果不存在)原型类。
这样的toJSON
将(仅在第一次调用时)将类原型中的getter(作为可枚举属性)添加到正在调用toJSON
的实例中。
当你装饰了多个吸气剂时,棘手的部分是,当处理第二个和装饰器时,区分你所拥有的toJSON
是否由你创造(然后你可以"追加"当前装饰器的属性)或者它是否在最初的类中(在这种情况下你会忽略)。很棘手,但据我所知,可行。
根据要求,你去吧。 serialization of arrays
class MyClass {
constructor(public name) {}
@enumerable(true)
get location(): string {
return 'Hello from Location!'
}
@enumerable(true)
get age(): number {
return 12345;
}
get sex(): string {
return "f";
}
}
class MyClassWithToJson {
constructor(public name) {}
@enumerable(true)
get nickname(): string {
return 'I shall still be non enumerable'
}
toJSON() { return 'Previously existing toJSON()!' }
}
function enumerable(value: boolean) {
return function (target: any, propertyKey: string) {
if (!value) {
// didnt ask to enumerate, nothing to do because even enumerables at the prototype wont
// appear in the JSON
return;
}
if (target.toJSON && !target.__propsToMakeEnumerable) {
return; // previously existing toJSON, nothing to do!
}
target.__propsToMakeEnumerable = (target.__propsToMakeEnumerable || []).concat([{propertyKey, value}])
target.toJSON = function () {
let self = this; // JSFiddle transpiler apparently is not transpiling arrow functions properly
if (!this.__propsToMakeEnumerableAlreadyProcessed) { // so we just do this once
console.log('processing non-enumerable props...'); // remove later, just for testing
let propsToMakeEnumerable = self.__propsToMakeEnumerable;
(propsToMakeEnumerable || []).forEach(({propertyKey, value}) => {
let descriptor = Object.getOwnPropertyDescriptor(self.__proto__, propertyKey);
descriptor.enumerable = true;
Object.defineProperty(self, propertyKey, descriptor);
});
Object.defineProperty(this, '__propsToMakeEnumerableAlreadyProcessed', {value: true, enumerable: false});
}
return this;
}
};
}
let obj = new MyClass('Bob');
console.log(JSON.stringify( obj ));
console.log(JSON.stringify( obj )); // this second time it shouldn't print "processing..."
console.log(JSON.stringify( new MyClassWithToJson('MyClassWithToJson') ));
答案 1 :(得分:0)
嗯,我很确定你真的不能,AFAIK标准说JSON.stringify
只会输出一个对象自己的可枚举属性。我认为最简单的解决方案是使用JSON.stringify
到pass in the keys you want to whitelist的第二个参数,这将使它使用您自己的键列表而不是我认为它们从{{1}获得的列表}:
Object.getOwnPropertyNames