Понятно, что когда атрибут (например, id ) существует / определяется в скрипте, мы должны использовать obj[id]
, а не eval('obj.' + id)
. Тем не менее, я еще не нашел решения для случая, когда имя атрибута само по себе является переменной и не определено - например, при получении в качестве параметра. В моем случае на сервере есть файл node.js, который получает объект JSON requestData , отправляемый клиентом через socket.io. requestData содержит пару ключ / значение: requestData.key - это массив имен узлов, которые составляют путь JSON к элемент, а requestData.val - это значение, которое будет сохранено в этом элементе.
В серверном скрипте есть определенный объект JSON с именем root , который содержит информацию, относящуюся к приложению, например:
"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()
?
Как я уже говорил, я не знаю названий тех элементов, которые будут отправлены с клиента. Все, что у меня есть на сервере, - это один объект JSON с именем «root», и я хочу постоянно добавлять / обновлять его по мере получения данных от клиента.
Я пробовал решения, основанные на JEXL или Mathjs, но, похоже, не работает для этого типа случая.