将JSON对象映射到Javascript对象

rya*_*dlf 17 javascript json

当使用AJAX时,我倾向于以JSON对象(又称Javascript)的形式将对象从我的服务器传递给Javascript.我的Javascript中的某些函数依赖于我正在使用的特定类型的对象.例如,让我们使用电话号码.我有一个构造函数:

function PhoneNumber(number, type, isPrimary, contactId, id, className) {
    this.number = number;
    this.type = type;
    this.isPrimary = isPrimary;
    this.contactId = contactId;
    this.id = id;
    this.className = className;
}
Run Code Online (Sandbox Code Playgroud)

在我的Javascript中创建电话号码对象时使用的.在某些情况下,我不在JS中创建对象,我从服务器获取对象,因此它以具有完全相同字段的通用对象的形式出现.因此,当我的代码依赖于特定类型时,使用如下内容:

var objType = objArray[i].constructor.name;
var mappedObj;

switch(objType) {
    case 'PhoneNumber':
        currentArray = currentArray.phone;
        //Convert response to javascript object.
        mappedObj = mapPhone(jsonResponse[i]);
        break;
    case 'Email':
        currentArray = currentArray.email;
        mappedObj = mapEmail(jsonResponse[i]);
        break;
    case 'Address':
        currentArray = currentArray.address;
        mappedObj = mapAddress(jsonResponse[i]);
        break;
    case 'Website':
        currentArray = currentArray.website;
        mappedObj = mapWebsite(jsonResponse[i]);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我检查对象构造函数的名称,并根据该名称设置某些变量.如果我检查名称的对象是来自服务器的JSON,它只是给我一个通用的"对象"响应,因此代码不起作用.我通过为每个对象使用映射函数来解决这个问题,例如:

function mapPhone(phoneObj) {
    var id = phoneObj.id;
    var contactId = phoneObj.contactId;
    var number = phoneObj.number;
    var type = phoneObj.type;
    var primary = phoneObj.isPrimary;
    var className = phoneObj.className;
    var phoneNumber = new PhoneNumber(number, type, primary, contactId, id, className);
    return phoneNumber;
}
Run Code Online (Sandbox Code Playgroud)

这很好用,但对我来说似乎有点多余.这是解决JSON对象问题的最佳方法,还是有更好的解决方案?我理解这更像是"我这样做是最好的方式"类型的问题,但我在我的Javascript代码中不断重复这种类型的逻辑,我想我也可能会得到另一个或两个关于它的意见在我必须花费一小时一小时来修复它之前,这样做的正确方法.

编辑:我最终接受了jQuery解决方案,因为我碰巧在我的项目中使用了jQuery.然而,在找到jQuery选项之前,有多个解决方案对我有用.他们只是不那么干净和高效.

Thi*_*ter 27

以下内容要求您在对象和JSON对象中具有相同的属性.

var phoneNumber = $.extend(new PhoneNumber(), yourJSONObject);
Run Code Online (Sandbox Code Playgroud)

这基本上创建了一个新的PhoneNumber对象,然后将JSON对象中的所有属性复制到它上面.该$.extend()方法来自jQuery,但您也可以使用来自例如Underscore.js或其他js库/框架之类的方法.

  • 如果你使用angular,你可以做`var phoneNumber = angular.copy(yourJSONObject,new PhoneNumber())`.我可能没有正确的语法,但你可以做到,这就是你想要的功能! (3认同)

Lev*_*evi 5

这个类似的问题有很多有趣的答案:

将 JSON 字符串解析为 JavaScript 中的特定对象原型

根据海报自己的回答,我认为这对您来说是一个有效的解决方案:

function recastJSON(jsonObject) {
    // return generic object if objectType is not specified
    if (!jsonObject.objectType)
        return jsonObject;

    // otherwise create a new object of type specified
    var obj = eval('new '+jsonObject.objectType+'()');
    for(var i in jsonObject)
        obj[i] = jsonObject[i];
    return obj;
}
Run Code Online (Sandbox Code Playgroud)

您需要将 objectType 添加到您收到的 JSON 对象以定义要实例化的 javascript 类。然后,当您调用此函数时,它会将对象强制转换为该类型并复制数据(包括变量“objectType”)。

使用您的电话号码示例,您的代码如下所示:

// generic object from JSON
var genericObject = {objectType:'PhoneNumber', number:'555-555-5555', type:'home', primary:true, contactId:123, id:1234, className:'stdPhone'};
var phoneObject = recastJSON(genericObject);
Run Code Online (Sandbox Code Playgroud)