Динамическая глубокая настройка для объекта JavaScript
С учетом строки для пути свойств объекта, как я могу установить это свойство динамически.
Учитывая этот образец объекта:
var obj = {
a: {
b: [ { c: 'Before' } ]
}
};
Он должен иметь возможность установить значение с помощью вспомогательной функции, например:
setToValue(obj, 'After', 'a.b.0.c');
Я попробовал его со следующим кодом. Но родитель является копией, если переменная не является ссылкой.
function setToValue(obj, value, path) {
var arrPath = path.split('.'),
parent = obj;
for (var i = 0, max = arrPath.length; i < max; i++) {
parent = parent[arrPath[i]];
}
parent = value;
}
Ответы
Ответ 1
a) Что не так с простым a.b [0].c = 'После'?
Что касается метода:
function setToValue(obj, value, path) {
var i;
path = path.split('.');
for (i = 0; i < path.length - 1; i++)
obj = obj[path[i]];
obj[path[i]] = value;
}
Здесь JSFiddle: http://jsfiddle.net/QycBz/24/
Ответ 2
Вот полное решение.
Также создает объекты, если они не существуют.
function setValue(obj, path, value) {
var a = path.split('.')
var o = obj
while (a.length - 1) {
var n = a.shift()
if (!(n in o)) o[n] = {}
o = o[n]
}
o[a[0]] = value
}
function getValue(obj, path) {
path = path.replace(/\[(\w+)\]/g, '.$1')
path = path.replace(/^\./, '')
var a = path.split('.')
var o = obj
while (a.length) {
var n = a.shift()
if (!(n in o)) return
o = o[n]
}
return o
}
Ответ 3
FWIW, те, кто желают этого в CoffeeScript, могут найти эти методы удобными - это довольно прямой порт вышеуказанного кода. В качестве дополнительного бонуса они гарантируют, что все объекты в пути существуют (getPropertyByPath не генерирует исключений, если они этого не делают, и метод set создает пустые объекты, если любые объекты в пути оказываются нулевыми).
getPropertyByPath: (obj, path) ->
path = path.split('.')
parent = obj
if path.length > 1
parent = parent[path[i]] for i in [0..path.length - 2]
parent?[path[path.length - 1]]
setPropertyByPath: (obj, path, value) ->
path = path.split('.')
parent = obj
if path.length > 1
parent = (parent[path[i]] ||= {}) for i in [0..path.length - 2]
parent[path[path.length - 1]] = value