【发布时间】:2021-08-19 00:15:59
【问题描述】:
我一直在使用以下函数的一个版本来创建和/或向嵌套对象添加值:
function assign(obj, keyPath, value) {
const lastKeyIndex = keyPath.length-1;
for (let i = 0; i < lastKeyIndex; ++ i) {
const key = keyPath[i];
if (!(key in obj)){
obj[key] = {}
}
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}
(由 kennytm 于 2011 年发表,以上稍作修改: Javascript: how to dynamically create nested objects using object names given by an array)。
指定值的示例用法,其中键表示 (0) 数据库 名称、(1) 表名、(3) id 值和(4) 列名:
let obj = {}
assign(obj, ['farm', 'products', '25', 'product_name'], 'lettuce');
console.log(JSON.stringify(obj));
/* (reformatted)
{
"farm": {
"products": {
"25": {
"product_name":"lettuce"
}
}
}
}
*/
我们可以为同一行添加第二个值:
assign(obj, ['farm', 'products', '25', 'product_unit'], 'head');
console.log(JSON.stringify(obj));
/* (reformatted)
{
"farm": {
"products": {
"25": {
"product_name":"lettuce",
"product_unit":"head"
}
}
}
}
*/
或来自不同行、表和数据库的附加值:
assign(obj, ['farm', 'equipment', '17', 'equipment_name'], 'tractor');
console.log(JSON.stringify(obj));
/* (reformatted)
{
"farm": {
"products": {
"25": {
"product_name": "lettuce",
"product_unit": "head"
}
},
"equipment": {
"17": {
"equipment_name": "tractor"
}
}
}
}
*/
该函数运行良好,但我不知道它是如何管理聚合关键路径的。它似乎只是用仅包含最后一个键和值的对象创建或替换现有对象。事实上,如果我不在函数内部且不使用循环执行相同的语句,这些语句就是这样做的。
(从将第一个值分配给空对象开始):
let obj = {}
let key;
// first iteration of the function's loop
key = 'farm';
if (!(key in obj)) {
obj[key] = {}
}
obj = obj[key];
// second iteration
key = 'products';
if (!(key in obj)) {
obj[key] = {}
}
obj = obj[key];
// third iteration
key = '25';
if (!(key in obj)) {
obj[key] = {}
}
obj = obj[key];
// final line from the function
obj['product name'] = 'lettuce';
console.log(JSON.stringify(obj));
// {"product name":"lettuce"}
如您所见,对象不是嵌套的,而是在每个步骤中简单地替换。
什么魔法使函数的工作方式不同?
【问题讨论】:
-
从
const myObj = {}; assign(myObj, ['farm', 'products', '25', 'product_name'], 'lettuce'); console.log(myObj)开始可能会有所帮助 - 与函数参数obj命名不同。
标签: javascript function object