Convert JavaScript string in dot notation into an object reference

前端 未结 27 3008
梦如初夏
梦如初夏 2020-11-21 05:09

Given a JS object

var obj = { a: { b: \'1\', c: \'2\' } }

and a string

\"a.b\"

how can I convert the stri

相关标签:
27条回答
  • 2020-11-21 05:40

    Here is my code without using eval. Its easy to understand too.

    function value(obj, props) {
      if (!props) return obj;
      var propsArr = props.split('.');
      var prop = propsArr.splice(0, 1);
      return value(obj[prop], propsArr.join('.'));
    }
    
    var obj = { a: { b: '1', c: '2', d:{a:{b:'blah'}}}};
    
    console.log(value(obj, 'a.d.a.b')); //returns blah
    
    0 讨论(0)
  • 2020-11-21 05:40

    Few years later, I found this that handles scope and array. e.g. a['b']["c"].d.etc

    function getScopedObj(scope, str) {
      let obj=scope, arr;
    
      try {
        arr = str.split(/[\[\]\.]/) // split by [,],.
          .filter(el => el)             // filter out empty one
          .map(el => el.replace(/^['"]+|['"]+$/g, '')); // remove string quotation
        arr.forEach(el => obj = obj[el])
      } catch(e) {
        obj = undefined;
      }
    
      return obj;
    }
    
    window.a = {b: {c: {d: {etc: 'success'}}}}
    
    getScopedObj(window, `a.b.c.d.etc`)             // success
    getScopedObj(window, `a['b']["c"].d.etc`)       // success
    getScopedObj(window, `a['INVALID']["c"].d.etc`) // undefined
    
    0 讨论(0)
  • 2020-11-21 05:42

    Other proposals are a little cryptic, so I thought I'd contribute:

    Object.prop = function(obj, prop, val){
        var props = prop.split('.')
          , final = props.pop(), p 
        while(p = props.shift()){
            if (typeof obj[p] === 'undefined')
                return undefined;
            obj = obj[p]
        }
        return val ? (obj[final] = val) : obj[final]
    }
    
    var obj = { a: { b: '1', c: '2' } }
    
    // get
    console.log(Object.prop(obj, 'a.c')) // -> 2
    // set
    Object.prop(obj, 'a.c', function(){})
    console.log(obj) // -> { a: { b: '1', c: [Function] } }
    
    0 讨论(0)
  • 2020-11-21 05:43
    var a = { b: { c: 9 } };
    
    function value(layer, path, value) {
        var i = 0,
            path = path.split('.');
    
        for (; i < path.length; i++)
            if (value != null && i + 1 === path.length)
                layer[path[i]] = value;
            layer = layer[path[i]];
    
        return layer;
    };
    
    value(a, 'b.c'); // 9
    
    value(a, 'b.c', 4);
    
    value(a, 'b.c'); // 4
    

    This is a lot of code when compared to the much simpler eval way of doing it, but like Simon Willison says, you should never use eval.

    Also, JSFiddle.

    0 讨论(0)
  • 2020-11-21 05:45

    I used this code in my project

    const getValue = (obj, arrPath) => (
      arrPath.reduce((x, y) => {
        if (y in x) return x[y]
        return {}
      }, obj)
    )
    

    Usage:

    const obj = { id: { user: { local: 104 } } }
    const path = [ 'id', 'user', 'local' ]
    getValue(obj, path) // return 104
    
    0 讨论(0)
  • 2020-11-21 05:46

    Many years since the original post. Now there is a great library called 'object-path'. https://github.com/mariocasciaro/object-path

    Available on NPM and BOWER https://www.npmjs.com/package/object-path

    It's as easy as:

    objectPath.get(obj, "a.c.1");  //returns "f"
    objectPath.set(obj, "a.j.0.f", "m");
    

    And works for deeply nested properties and arrays.

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