自动嵌套对象

Automated nested objects

几天前,我在玩一些js,当我遇到一个问题时,我是否可以自动化对象嵌套。当然我还是个新人,所以我还没有走得太远。

但我得到的是:

var a = {};
var stso = ""; storing the second object

function sto(b) { // start the object
    a[b] = {};
    stso = b;
}

function nmo(...objs) { // nesting more object
    console.log(objs[0]);
    if(objs.length) { // checking to see that I have at least one variable before proceding
        for(i = 0; i < objs.length; i++) { // looping through arguments
            a[stso][objs[i]] = {}; // and now I would have to repeat one more more for lever for every argument, meaning, the deeper I want to go into the object, the more nested for loops I have to make.
        }
    }
}

sto("b");
nmo("c");
a.b.c = "Happy ending!";

console.log(a.b.c); // It seems we still dont have a happy ending

// and as a second example

sto("b");
nmo("c", "d", "e", "f", "g");
a.b.c.d.e.f.g = "Another happy ending!";

console.log(a.b.c.d.e.f.g); // Our second happy ending was also unhappy...

总而言之,您在一个函数中定义了第二个对象,您可以在第二个函数中按顺序定义任意数量的对象。

如何使用我当前的结构实现此目标?

如果我理解正确的话,你可以这样做:

var createNestedObjects = function( obj ) {
    //get all the passed arguments 
    var args = Array.prototype.slice.call(arguments);

    //start with i = 1, as we want to skip obj in the arguments
    for( var i = 1; i < args.length; i++ ) {
        obj = obj[ args[i] ] = obj[ args[i] ] || {};
    }

};

var a = {};
createNestedObjects( a, "b", "c", "d", "e", "f" );
a.b.c.d.e.f = "happy ending";
console.log(a.b.c.d.e.f); //logs "happy ending"

说明第 3 行

您的要求是将尽可能多的字符串传递给函数以创建您想要的任意大小的嵌套对象。 但是,如您所见,该函数只有一个参数:obj。 很酷的是 javascript 允许您传递更多参数,并且您仍然可以使用 arguments 对象访问它们。 arguments 对象在所有函数中都可用。 arguments 对象类似于一个数组,但又不完全相同,因为它本身就是一个对象,如果您在这种情况下记录它,它将显示:

Arguments [{}, "b", "c", "d", "e", "f"] (6) 

我们不能使用 for 循环遍历 agruments 对象,所以在第 3 行它首先被转换为数组。 arguments object reference


循环内解释

这一行有两个有趣的部分。 Javascript 允许您一次分配多个变量,因为赋值运算符根据其右操作数的值为其左操作数分配一个值

  var a, b;
  a =  b = 10; //both a and b are set to 10

使用 ||如果左侧的值未定义,则此处使用运算符设置默认值(在本例中为 {})。例如,设置默认值也很方便

function setDelay ( delay ){

    delay = delay || 60
    return delay

}

setDelay(  ) //no parameter is passed, delay is set to 60 
setDelay( 120 ) 120 is passed and delay is set to 120

在这种情况下,行

obj = obj[ args[i] ] = obj[ args[i] ] || {};

可以改写为:

var name = args[i];    // first loop args[i] is "b"    
if(!obj[name]){        // a.b does not exist       
    obj[name] = {};    // a.b is set to {}      
}
obj = obj[name];       // a is set to a.b 

检查是否已经存在同名对象,如果不存在则创建对象并将其设置为 obj,以便我们可以在下一个循环中嵌套对象。

我希望这能澄清代码

所以,您想将值转换为嵌套对象?这可以通过做这样的事情来完成:

let values = ['b', 'c', 'd', 'e', 'f', 'g'];
let a = {};
// Every time we loop, we change the root
let root = a;

for (let value of values) {
  // Set root to the value of the array and assign a new object
  root = root[value] = {};
}
// Set the string
a.b.c.d.e.f.g = "Happy ending!";

console.log(a.b.c.d.e.f.g);
console.log(a);

它基本上是在循环内完成的:

a = a[b] = {};
a[b] = a[b][c] = {};
a[b][c] = a[b][c][d] = {};
a[b][c][d] = a[b][c][d][e] = {};
a[b][c][d][e] = a[b][c][d][e][f] = {};
a[b][c][d][e][f] = a[b][c][d][e][f][g] = {};

它在每个循环中创建一个新键并为其分配一个空对象。下一次迭代在上一次循环中新创建的对象内创建一个新键(以空对象作为值)。这一直持续到数组的所有值都已分配。