Access deep properties and methods using a string path in javascript

javascript functional-programming

58 观看

1回复

1465 作者的声誉

I have a code snippet that I have been using and works. It is used a lot in my application and I need to speed it up. Is there a faster better way of deep accessing objects using as string path. It needs to able to access properties and methods, see my examples below:

     function get(obj, path) {
        var paths = path.split('.'),
        curProp = obj;
        for(var i=0;i<paths.length;i++){
            if (!curProp[paths[i]]) return 
            curProp = (typeof curProp[paths[i]] !== "function") ? curProp[paths[i]] : curProp[paths[i]]() ;
        }
        return curProp;
    }

The snippet gets the property via the path for the object passed

var obj = {contact:{name:"john"}};
console.log(get("contact.name",obj));

If the object has a method that returns an object it can return that too

var obj = {contact:function(){return {name:"john"}}};
console.log(get("contact.name",obj));
作者: MartinWebb 的来源 发布者: 2017 年 12 月 27 日

回应 1


1

79150 作者的声誉

The very nature of your question – ie, accessing deep properties programmatically – shows you're approaching functional programming with your own ideas of how it should work.

Functional-style programs will not use objects in this way. Even tho we can express your program in a functional style (below), whatever part of your program that uses the get function should probably be refactored not to use dynamic objects and dynamic object look-ups.

Similarly, using methods to store an object's values also comes from object-oriented style. Once you stop thinking about things in OO-style, you can begin to see the unique strengths of functional style.

const recur = (...values) =>
  ({ tag: recur, values })

const loop = (f) =>
  {
    let acc = f ()
    while (acc && acc.tag === recur)
      acc = f (...acc.values)
    return acc
  }

const get = (obj = {}, path = []) =>
   loop ((o = obj, [p, ...ps] = path.split ('.')) =>
     (p === undefined)
       ? o
       : o[p] === undefined
         ? undefined
         : recur (o[p], ps))

const data =
  { a: { b: { c: 1, d: null } } }

console.log (get (data, 'a'))      // { b: { c: 1 } }
console.log (get (data, 'a.b'))    // { c: 1 }
console.log (get (data, 'a.b.c'))  // 1
console.log (get (data, 'a.b.c.')) // undefined
console.log (get (data, 'd'))      // undefined
console.log (get (data, 'a.b.d'))  // null

作者: user633183 发布者: 2017 年 12 月 27 日
32x32