我想将一个示例类转换为普通对象,而不丢失方法和/或继承的属性。例如:
class Human {
height: number;
weight: number;
constructor() {
this.height = 180;
this.weight = 180;
}
getWeight() { return this.weight; }
// I want this function to convert the child instance
// accordingly
toJSON() {
// ???
return {};
}
}
class Person extends Human {
public name: string;
constructor() {
super();
this.name = 'Doe';
}
public getName() {
return this.name;
}
}
class PersonWorker extends Person {
constructor() {
super();
}
public report() {
console.log('I am Working');
}
public test() {
console.log('something');
}
}
let p = new PersonWorker;
let jsoned = p.toJSON();
jsoned
应该是这样的:
{
// from Human class
height: 180,
weight: 180,
// when called should return this object's value of weight property
getWeight: function() {return this.weight},
// from Person class
name: 'Doe'
getName(): function() {return this.name},
// and from PersonWorker class
report: function() { console.log('I am Working'); },
test: function() { console.log('something'); }
}
这是否可能实现,如果可能,如何实现?
如果你想知道,我需要这个,因为我使用的框架,不幸的是,只接受一个对象作为输入,而我试图使用TypeScript和类继承。
此外,我做了一次上述转换,所以性能不是一个需要考虑的问题。
如果编译器的target选项设置为es6
,则包含遍历对象属性的解决方案将不起作用。在es5
上,通过迭代对象属性(使用Object.keys(instance)
)的现有实现将工作。
到目前为止,我有这样的实现:
toJSON(proto?: any) {
// ???
let jsoned: any = {};
let toConvert = <any>proto || this;
Object.getOwnPropertyNames(toConvert).forEach((prop) => {
const val = toConvert[prop];
// don't include those
if (prop === 'toJSON' || prop === 'constructor') {
return;
}
if (typeof val === 'function') {
jsoned[prop] = val.bind(this);
return;
}
jsoned[prop] = val;
const proto = Object.getPrototypeOf(toConvert);
if (proto !== null) {
Object.keys(this.toJSON(proto)).forEach(key => {
if (!!jsoned[key] || key === 'constructor' || key === 'toJSON') return;
if (typeof proto[key] === 'function') {
jsoned[key] = proto[key].bind(this);
return;
}
jsoned[key] = proto[key];
});
}
});
return jsoned;
}
但这仍然不起作用。结果对象只包含所有类的所有属性,但只包含PersonWorker
的方法。我错过了什么?
7条答案
按热度按时间ctzwtxfj1#
已经有很多答案了,但这是最简单的,通过使用spread syntax和de-structuring对象:
8i9zcol22#
这就是我的工作
更新的答案(使用递归)
原始答案
a11xaf1n3#
好吧,所以我的OP中的实现是错误的,这个错误简直是愚蠢的。
使用
es6
时的正确实现是:agyaoht74#
下面是toJSON()方法的实现。我们正在将当前示例的属性和方法复制到一个新对象,并排除不需要的方法,即JSON和构造器
我已经在Chrome中测试了toJSON()返回的对象,我看到对象的行为与您期望的方式相同。
j2datikz5#
我反复引用了Alex Cory的解决方案,但这是我的最终结果。它期望被分配给一个类作为一个函数,并在
this
上有相应的绑定。那么如果你使用的是TypeScript,你可以把这个接口放在任何应该转换为对象的类上:
然后在类中,不要忘记绑定
this
syqv5f0l6#
这种解决方案将丢失方法,但将类示例转换为对象是一种非常简单的解决方案。
olmpazwi7#
使用Lodash
这个方法不是递归的。