自动嵌套对象

时间:2016-05-20 22:14:37

标签: javascript nested-loops javascript-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...

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

我如何用我目前的结构实现这一目标?

2 个答案:

答案 0 :(得分:1)

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

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

使用||如果左边的值未定义,则此处使用operator设置默认值(在本例中为{})。例如,设置默认值

也很方便
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,以便我们可以在下一个循环中嵌套对象。

我希望这能澄清代码

答案 1 :(得分:1)

那么,您想将值转换为嵌套对象吗?这可以通过这样做来完成:

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] = {};

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