2

我想通过每个 AJAX 加载数据来动态创建谷歌地图。因此,我使用具有与 GM API 相同结构的 JSON 对象来构建地图,并使用 jQuery 来加载每个 AJAX。

喜欢:

"object": {
    "div": "map1",
    "options": {
        "center": {
            "latitude": 38.608202,
            "longitude": 26.373749,
            "noWrap": false
        },
        "mapTypeId": "roadmap",
        "zoom": 7
    }
}

现在在 JSON 中包含原始 JavaScript 并使用 eval 函数解析它是否是一个好主意,例如:

"object": {
    "div": "map1",
    "options": {
        "center": new google.maps.LatLng( 38.608202, 26.373749 ),
        "mapTypeId": google.maps.MapTypeId.ROADMAP,
        "zoom": 7
    }
}

使用 jQuery 的默认 JSON 解析器我得到一个错误。但是,如果我使用 eval 函数创建自己的转换器,它就可以工作。

jQuery.ajax({
    url: this.url,
    data: this.parameters,
    type: method,
    dataType: 'json',
    converters: {'text json': function( data ){
        eval( 'data = ' + data );
        return data;
    }},
    […]
});

我知道这不是正确的 JSON 格式。但是我会因此遇到一些其他麻烦吗,或者是否有任何速度损失导致 eval 函数?

4

1 回答 1

0

现在在 JSON 中包含原始 JavaScript 并使用 eval 解析它是一个好主意吗?

不。部分是因为eval应该避免,但更重要的是因为你正在淡化关注点的分离。

JSON是数据。数据并不意味着代码。您的代码应使用此数据初始化其状态。这将是一种更好的方法来优化您的数据,这样您的代码就可以更智能地进行初始化。

顺便说一句,性能在这里不是你的问题,所以它不应该是你关心的问题之一。在性能好后明显变慢时处理优化性能,而不是之前。

怎么样

"object": {
    "div": "map1",
    "options": {
        "center": {
            "gmType": "LatLng",
            "init": [38.608202, 26.373749]
        },
        "mapTypeId": {
            "gmType": "MapTypeId",
            "init": "ROADMAP"
        },
        "zoom": 7
    }
}

// function from http://stackoverflow.com/a/3362623/
function construct(Constructor, args) {
    var Temp = function(){}, inst, ret;
    Temp.prototype = Constructor.prototype;
    inst = new Temp;
    ret = Constructor.apply(inst, args);
    return Object(ret) === ret ? ret : inst;
}

function jsonPrepare(jsonObject) {
    if ($.isPlainObject(jsonObject)) {
        $.each(jsonObject, function (key, item) {
            var target = null;
            if (item.hasOwnProperty("gmType")) {
                // initialize the GMaps object at this position
                target = google.maps[item.gmType];
                if ($.isFunction(target)) {
                    // ...either it is a constructor (like LatLng)
                    jsonObject[key] = construct(target, item.init);
                } else if (item.init in target) {
                    // ...or it is a look-up object (like MapTypeId)
                    jsonObject[key] = target[item.init];
                }
            } else {
                // recurse
                jsonPrepare(item);
            }
        });
    } else if ($.isArray(jsonObject)) {
        $.each(jsonObject, function (key, item) {
            // recurse
            jsonPrepare(item);
        });
    }
    return jsonObject;
}

jQuery.ajax({
    url: this.url,
    data: this.parameters,
    type: method,
    dataType: 'json'
}).then(jsonPrepare).then(function (data) {
    // your JSON object is now set up
}); 

这是有效的,因为jsonPrepare就地修改了对象实例。

更重要的是,您现在能够灵活地以声明方式在客户端中创建对象 - 而无需混合代码和数据。

于 2013-06-30T10:41:08.593 回答