javascript - 当节点/属性名称是变量/参数时寻找 eval() 替代方案

标签 javascript eval

很明显,当脚本中存在/定义了属性(例如id)时,我们应该使用obj[id] 而不是 eval('obj.' + id)。但是,对于属性名称本身是变量且未定义的情况,我还没有找到解决方案 - 例如当作为参数接收时。在我的例子中,我在服务器上有 node.js 接收一个 JSON 对象 requestData 从客户端通过 socket.io 发送。 requestData 包含键/值对:requestData.key 是组成节点名称的数组元素的 JSON 路径,requestData.val 是要存储在该元素中的值。

在服务器脚本中有一个名为 root 的已定义 JSON 对象,其中包含与应用程序相关的信息,例如:

"root": {
  "pages": {
    "TM1010": {
      "appId": "TM1010",
      "componentName": "UserTasksPage"
    },
    "TM1020": {
      "appId": "TM1020",
      "componentName": "UsersPage"
    }
  }
}

如果客户端要发送更新元素的请求 - 例如更改 root.pages.TM1010.componentName 的值 - 这就是它的方式从客户端发送:

let requestData = {'key': ['pages', 'TM1010', 'componentName'], 'val': newComponentName};
this.socket.emit('changeData', requestData);

这是它在服务器上接收和执行的方式:

socket.on('changeData', (requestData) => {
  var str = 'root'
  var key = requestData.key
  var len = key.length;
  for (var i = 0; i < len; i++) {
   str = str + '["' + key[i] + '"]'
  }
  str = str + '=requestData.val'
  eval(str)
});

这样最后执行的(str的值)就是:

root["pages"]["TM1010"]["componentName"]=requestData.val

如果没有 eval() 怎么能做到这一点?

如前所述,我不知道将从客户端发送的那些元素的名称。我在服务器上只有一个名为“root”的 JSON 对象,我想在从客户端接收数据时不断添加/更新它。 我尝试过基于 JEXL 或 mathjs 的解决方案,但它似乎不适用于此类情况。

最佳答案

您可以通过获取对象并使用最后一个键分配值来减少键。

const
    setValue = (object, keys, value) => {
        var path = keys.slice(),
            last = path.pop();
        path.reduce((o, k) => o[k], object)[last] = value;
    };

var data = { root: { pages: { TM1010: { appId: "TM1010", componentName: "UserTasksPage" }, TM1020: { appId: "TM1020", componentName: "UsersPage" } } } },
    requestData = { key: ['pages', 'TM1010', 'componentName'], val: 'newComponentName' };

setValue(data.root, requestData.key, requestData.val);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

关于javascript - 当节点/属性名称是变量/参数时寻找 eval() 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55010377/

相关文章:

javascript - 为什么在对字符串使用 setTimeout 时会看到不安全评估警报?

javascript - eval() 不起作用

php - 将 BASH 关联数组传递给 PHP 脚本

javascript访问手机相机的手电筒

javascript - 如何将 jQuery ng-repeat {{x.something}} 传递给 javascript api url,如/api/get_now/{{x.something}}

javascript - 移动和删除元素时鼠标输入

javascript - 编写 for 循环以使用数组创建多个方法

javascript - react-router "Cannot read property ' push' of undefined"

javascript - 如何在教育应用程序的 JavaScript 中安全地使用 eval()?

ruby-on-rails - 是否可以使用 "eval"来定义一个函数(而不是每个函数一个)?