我想要分配一个这样的值:
x.label1.label2.label3 = someValue;
// or equivalently:
x['label1']['label2']['label3'] = someValue;
只要定义了x.label1.label2
,它就会起作用,否则会遇到引用错误。这当然有道理。但是,它是否有一种简单的方法来分配它,只需创建必要的嵌套对象?
例如,如果x
等于{ label1: {}, otherLabel: 'otherValue' }
,我想将x
更新为{ label1: { label2: { label3: someValue } }, otherLabel: otherValue }
我想我可能自己编写一个函数,但有没有语言功能或标准库函数可以做到这一点?
答案 0 :(得分:1)
是否有语言功能或标准库功能来执行此操作
没有。您必须编写自己的函数或使用提供此类功能的库。
相关:How to set object property (of object property of..) given its string name in JavaScript?
答案 1 :(得分:1)
使用Proxy类可以部分实现。您可以将对象包装在Proxy中,并在访问不存在的属性时覆盖get
陷阱以创建同一代理的另一个副本。这使您可以递归地创建“深度”属性。一个例子:
let traps = {
get: function (target, name) {
if (!(name in target))
target[name] = new Proxy({}, traps);
return target[name];
}
};
let x = new Proxy({}, traps);
然后你会像任何对象一样使用x
,除非它有这种特殊行为:
x.label1.label2.label3 = 'foo';
创建对象的嵌套层次结构。但请注意,即使您访问不存在的属性,也会创建一个对象。因此,您必须使用in
关键字来检查它是否确实包含给定的属性。
答案 2 :(得分:1)
我认为你确实应该使用自定义功能,例如:
function assignByPath(obj, path, value) {
var field = path.split('>'),
last = field.pop();
field.reduce(
function(node, f) {
return node[f] = node[f] instanceof Object ? node[f] : {};
}, obj
)[last] = value;
}
var myObj = {};
assignByPath(myObj, 'label1>label2>label3', 'someValue');
console.log(myObj);
理论上,您还可以覆盖Object.prototype
,这样您就可以:
myObj.assignByPath('label1>label2>label3', 'someValue');
但我不建议这样做。
答案 3 :(得分:1)
您可以使用Array.prototype.shift()
,Object.assign()
,递归
var x = {
label1: {},
otherLabel: "otherValue"
};
var nestprops = (props, value, obj, o, curr = props.shift()) => props.length
? nestprops(props, value, (Object.assign(obj, {[curr]: {}}) && obj[curr]), o)
: ((!value || value) && (obj[curr] = value) && o);
console.log(nestprops(["label1", "label2", "label3"], "someValue", x, x));
答案 4 :(得分:0)
检查label1 object
内的键的长度是否等于0
,然后将其修改为所需的对象。
以下是代码段,希望有所帮助。
var obj = { label1: {}, otherLabel: 'otherValue' };
if(Object.keys(obj.label1).length == 0 ) {
obj.label1 = { label2: { label3: "value3" } };
}
console.log(obj);