Creating an object with sub-objects up to the nth level

I have an object with a name and a method with a name whose purpose is to create a new property for and a sub-property for the property or just skip it at all if it already exists. MyObject createEntry() MyObject

My code is:

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");

As shown in the above function, I am trying to create a new sub-object for each argument of the method , with the exception of the last two, where is this or and . createEntry() val3 property method val4

When my method is in its current state, I can only reach level 3 with its subsequent requirements requiring a longer and longer code. I assume that the above can be achieved with a loop , but I have not yet been able to understand it. while

:. - , , , :

var MyObject = {
   val1: {
      val2 {
         val3: val4
      }
   }
}
+4
3

Oriol , - , , , MyObject.

, MyObject return, - , 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];
   }
}

, , @Oriol return expand():

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);
Hide result

!

0

reduceRight :

function createEntry(...args) {
  return args.reduceRight(function(prev, curr) {
    return {[curr]: prev};
  });
}
console.log(createEntry("val1", "val2", "val3", "val4"));
Hide result
+4

, - , , . .

. 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: {
            }
       }
   }
*/

, ,

+1

Source: https://habr.com/ru/post/1654753/


All Articles