Automatically create object if undefined

后端 未结 12 1035
Happy的楠姐
Happy的楠姐 2020-12-07 13:07

Is there an easy way to automatically add properties to objects if they don\'t allready exist?

Consider the following example:

var test = {}
test.hel         


        
相关标签:
12条回答
  • 2020-12-07 13:34

    You won't be able to do this without some sort of function, as JavaScript doesn't have a generic getter/setter method for objects (Python, for example, has __getattr__). Here's one way to do it:

    function add_property(object, key, value) {
        var keys = key.split('.');
    
        while (keys.length > 1) {
            var k = keys.shift();
    
            if (!object.hasOwnProperty(k)) {
                object[k] = {};
            }
    
            object = object[k];
        }
    
        object[keys[0]] = value;
    }
    

    If you really want to, you could add it to the prototype of Object. You can call it like so:

    > var o = {}
    > add_property(o, 'foo.bar.baz', 12)
    > o.foo.bar.baz
    12
    
    0 讨论(0)
  • 2020-12-07 13:35

    I've come up with something, really custom as well, but it works as far as I have tested.

    function dotted_put_var(str,val) {
        var oper=str.split('.');
        var p=window;
        for (var i=0;i<oper.length-1;i++) {
            var x=oper[i];
            p[x]=p[x]||{};
            p=p[x];
        }
        p[oper.pop()]=val;
    }
    

    Then, a complex variable can be set like this, ensuring that every links will be created if not already:

    dotter_put_var('test.hello.world', 'testvalue'); // test.hello.world="testvalue";
    

    See this working FIDDLE.

    0 讨论(0)
  • 2020-12-07 13:35

    let test = {};
    test = {...test, hello: {...test.hello, world: 'Hello does exist!'}};
    console.log(test);

    When using the spread operator, the value can be undefined, it'll automatically create an object.

    0 讨论(0)
  • 2020-12-07 13:38

    This will add a property hello whose value is {world: 'Hello world!'} to the test object, if it doesn't exist. If you have a lot of these objects, you can just iterate over them and apply this function. Note: uses lodash.js

    var test = {};
    _.defaults(test, { hello: {world: 'Hello world!'} });    
    

    Which is actually a convenience method for saying:

    var defaults = _.partialRight(_.assign, function(a, b) {
      return typeof a == 'undefined' ? b : a;
    });        
    defaults(test, { hello: {world: 'Hello world!'} });
    

    Note: _.defaults uses loops to achieve the same thing as the second block.

    P.S. Checkout https://stackoverflow.com/a/17197858/1218080

    0 讨论(0)
  • 2020-12-07 13:42

    I use this:

    Object.prototype.initProperty = function(name, defaultValue) {
      if (!(name in this)) this[name] = defaultValue;
    };
    

    You can later do f.e.:

    var x = {a: 1};
    x.initProperty("a", 2); // will not change property a
    x.initProperty("b", 3); // will define property b
    console.log(x); // => {a: 1, b: 3}
    
    0 讨论(0)
  • 2020-12-07 13:45

    I've made some changes on columbus's answer to allow create arrays:

    function addProps(obj, arr, val) {
    
      if (typeof arr == 'string')
        arr = arr.split(".");
    
      var tmpObj, isArray = /^(.*)\[(\d+)\]$/.exec(arr[0])
      if (isArray && !Number.isNaN(isArray[2])) {
        obj[isArray[1]] = obj[isArray[1]] || [];
        obj[isArray[1]][isArray[2]] = obj[isArray[1]][isArray[2]] || {}
        tmpObj = obj[isArray[1]][isArray[2]];
      } else {
        obj[arr[0]] = obj[arr[0]] || {};
        tmpObj = obj[arr[0]];
      }
    
      if (arr.length > 1) {
        arr.shift();
        addProps(tmpObj, arr, val);
      } else
        obj[arr[0]] = val;
    
      return obj;
    
    }
    
    
    var myObj = {}
    addProps(myObj, 'sub1[0].sub2.propA', 1)
    addProps(myObj, 'sub1[1].sub2.propA', 2)
    
    console.log(myObj)

    I think that is possible to allow use "sub1[].sub2..." to just push into the sub1 array, instead of specify the index, but that's enough for me now.

    0 讨论(0)
提交回复
热议问题