如何在不使用 eval() 的情况下从字符串运行 JavaScript 对象

how to run javascript object from string without using eval()

本文关键字:情况下 字符串 运行 对象 JavaScript eval      更新时间:2023-09-26

我有一个具有项目类型和ID的json对象,我需要创建新对象

var data = { 
            "items":[
                    {"type":"generator","id":"item_1","x":200,"y":200},
                    {"type":"battery","id":"item_2","x":50,"y":300},
                    {"type":"generator","id":"item_3","x":200,"y":280},
                    {"type":"battery","id":"item_4","x":100,"y":400}
                ]
        };

我需要为项目中的每个项目运行

jQuery.each(data.items, function(index,value) {
    eval("var " + value.id + " = new " + value.type + "(" + (index + 1) + ");");
    eval(value.id + ".id = '" + value.id + "';");
    eval(value.id + ".draw(" + value.x + "," + value.y + ");")
});

这不是一个好的做法,但我还能做什么?

然后我需要控制项目

类似的东西

    item_1.moveto(300,700);

但我总是得到item_1是找不到的

您可以创建一个工厂方法,该方法允许从抽象数据结构中生成具体类型:

var createItem = (function () {
    var types = {};
    function createItem(index, data) {
        data = data || {};
        var ctor = types[data.type], item;
        if (!ctor) throw new Error("'" + data.type + "' is not a registered item type.");
        item = new ctor(index);
        item.id = data.id;
        return item;
    }
    createItem.registerType = function (type, ctor) {
        types[type] = ctor;
    };
    return createItem;
})();

然后将项目类型注册到工厂:

function Generator(index) {/*...*/}
createItem.registerType('generator', Generator);

最后创建一个对象映射以按 id 查找您的项目(您可以使用像 ItemsMap 这样的专用对象而不是普通对象),循环访问您的项目并将它们添加到地图中。

var itemsMap = {};
data.items.forEach(function (itemData, i) {
    var item = itemsMap[itemData.id] = createItem(i + 1, itemData);
    //you can also draw them at this point
    item.draw(itemData.x, itemData.y);
});

您现在可以按 id 查找对象,如下所示:

var item1 = itemsMap['item_1'];
var objects = {};
objects[value.id] = new window[value.type](index + 1);
相关文章: