我有一个名为 MyObject
的对象和一个名为 createEntry()
的方法,旨在为 {{1}创建一个新属性和属性的子属性,如果它已经存在,则完全跳过它。
我的代码:
MyObject
如上面的函数所示,我正在尝试为方法 var MyObject = {
createEntry: function (val1, val2, val3, val4) {
this[val1] = this[val1] || {};
this[val1][val2] = this[val1][val2] || {};
this[val1][val2][val3] = val4;
}
};
MyObject.createEntry("val1", "val2", "val3", "val4");
的每个参数创建一个新的子对象,除了最后两个,其中 { {1}} 是 createEntry()
或 val3
, property
是其值。
当我的方法处于当前状态时,我只能达到3级,其后续的需要更长和更长的代码。我假设使用 method
循环可以实现上述目标,但我还没有弄明白。
问题:如何根据上面函数传递的参数数量创建无限制的子对象,树形方式如下所示:
val4
答案 0 :(得分:4)
reduceRight
似乎是完美的:
function createEntry(...args) {
return args.reduceRight(function(prev, curr) {
return {[curr]: prev};
});
}
console.log(createEntry("val1", "val2", "val3", "val4"));
答案 1 :(得分:1)
好吧,当使用参数创建无限的子对象时,我会迭代每个参数,将我输入的最后一个对象作为参考。这段代码足以理解。
注意:Object.assign
是一个新的浏览器实现,但它已经有polyfills。当对象中已存在条目名称时,我使用此方法将对象与对象连接起来
Object['prototype']['createEntries'] = function() {
/* store last object location */
var lastObj = this
/**
* Note: each argument is a object that specify the following properties -->
* inner : the entry object
* *name : the entry property name
*/
for (var i = 0, arg, existent, len = arguments.length; i < len; ++i) {
if (typeof (arg = arguments[i]) === 'object' && (typeof arg.inner === 'object' ? true : arg.inner = {} ))
/* create new entry/keep existent entry and reserve it in lastObj */
lastObj = (typeof (existent = lastObj[arg.name]) === 'object' ?
lastObj[arg.name] = Object.assign(existent, arg.inner) :
lastObj[arg.name] = arg.inner)
}
return this
}
然后这是一个基本用法
({}).createEntries({
name: "val1"
}, {
name: "val2"
})
/* {
val1: {
val2: {
}
}
}
*/
我希望这就是你想要的
答案 2 :(得分:0)
Oriol给了一个很棒的answer,但是由于它的构建方式,他的功能并没有真正用处,因为它返回一个新对象而不是修改 MyObject
。
因此,为了实际修改 MyObject
,而不是第一个 return
,我们必须做一些其他修改< strong> MyObject
,不会覆盖它。
要做到这一点,必须构建一个扩展 MyObject
的函数:
expand: function (object) {
for (var key in object) if (!!object[key]) {
if (key in this) throw new Error("`" + key + "` already exists.");
else this[key] = object[key];
}
}
然后,我们所要做的就是在没有第一个 return
语句的情况下使用@Oriol的答案作为 expand()
的参数:< / p>
createEntry: function () {
this.expand([].reduceRight.call(arguments, function(previous, current) {
return {[current]: previous};
}));
}
完整代码:
var MyObject = {
createEntry: function() {
this.expand([].reduceRight.call(arguments, function(previous, current) {
return {
[current]: previous
};
}));
},
expand: function(object) {
for (var key in object)
if (!!object[key]) {
if (key in this) throw new Error("`" + key + "` already exists.");
else this[key] = object[key];
}
}
};
MyObject.createEntry("val1", "val2", "val3", "val4");
console.log(MyObject);
感谢大家的帮助!