我的客户端代码获取了一个JSON'对象'从服务器,然后解析它。解析的对象包含'类型' property,它应该控制对象的类。
$.getJSON("foo.json").done(function(data, textStatus, xhr) {
$.each(data.objects, function(key, val)
{
if (val.type = "A") // make val into an object of class A, somehow?
...
else if (val.type = "B") // make val into an object of class B somehow?
... etc...
}
}
如何在不显式复制每个属性的情况下创建正确类型的JavaScript对象,或者 - 将解析后的对象转换为其他类型?
我已经阅读了一些关于__proto__
的内容,但感觉它对于应该是一个小小的坚果来说是一个很大的大锤...
我见过类似的关于Java和Jackson的问题,但Javascript没有...
答案 0 :(得分:4)
你可以做这样的事情
function ObjectFactory() {
this.newInstance = function(val) {
if (val.type == "A") return new A(val);
if (val.type == "B") return new B(val);
}
}
function A(data) {
// do something with the data
this.property = data.property;
}
function B(data) {
// do something with the data
this.property = data.property;
this.bSpecificProperty = data.bSpecificProperty;
}
$.getJSON("foo.json").done(function(data, textStatus, xhr) {
var objectFactory = new ObjectFactory();
var objects = $.map(data.objects, objectFactory.newInstance);
console.log(objects);
}
如果你有一个更好的例子来说明正确的类型,以及一些样本数据,我可以提供更好的答案。
答案 1 :(得分:2)
你还没有指定你正在实施的模式 - 如果有的话 - 但正如另一个答案所暗示的那样,你必须在对象的构造过程中采用某种约定。您不一定要明确说明每个类型,但您也可能有点懒惰将 JSON 数据与$.extend
合并如果你对它的完整性感到满意吗?
我还包含一个辅助函数,用于解析给定范围内的"类型" - 它是命名空间的常见做法>项目中的对象,以避免污染全局范围。例如:
function namespace(str, scope){
scope = scope || window;
var parts = str.split('.');
while(parts.length)
scope = scope[parts.shift()];
return scope;
}
Foo = {};
Foo.Bar = function(conf){
// some kind of constructor
$.extend(this, conf);
};
// test...
var json = {
type: 'Foo.Bar',
var1: 1,
var2: 2,
var3: 3
};
var obj = new (namespace(json.type))(json);
console.log(obj, obj instanceof Foo.Bar);
fiddle ...或者适合您自己的代码:
$.getJSON("foo.json").done(function(data, textStatus, xhr){
data.objects = $.map(data.objects, function(obj){
return new (namespace(obj.type))(obj);
});
});