简体   繁体   中英

How to access property of a nested object?

I have the following Javascript object:

doc = {};
doc.title = 'a title';
doc.date = 'a date';
doc.send = {
    date: new Date(),
    sender: 'a sender',
    receiver: 'a receiver'
};

And i have the following function:

doSomething(item, property) {
    console.log(item[property];
}

It works if i call doSomething(doc, 'date') , but it doesn't work if i use doSomething(doc, 'send.date') . Since that function have to be reusable, how to let it handling any type of property, including nested one?

I see that lodash could be helpful with _.get , but i'm using underscore that not include that method. In addition i prefer not to use and install other libraries. Any idea?

You can write a function to find (nested) property value, for example:

function findDeepProp(obj, prop) {
    return prop.split('.').reduce((r, p)=> r[p], obj)
}
findDeepProp(doc, 'title'); // a title
findDeepProp(doc, 'send.sender'); // a sender

This is a bit dangerous depending on what you're trying to do, I recommend you to read this , but I think this will work:

doSomething = function(element, property){
    console.log(eval("element." + property));
}

If you wanted to check more than one level of nesting you could use a function that uses recursion.

var doc = {
  title: 'a title', date: 'a date',
  send: { date: +new Date(), sender: 'a sender', receiver: 'a receiver',
    thing: {
      fullname: { first: 'Bob', last: 'Smith' }
    }
  }
}

function findDeepProp(obj, prop) {

  // create an array from the props argument
  var target = prop.split('.'), out;

  // iteration function accepts an object and target array
  (function iterate(obj, target) {

    // remove the first array element and assign it to tmp
    var tmp = target.shift();

    // if target has no more elements and tmp
    // exists as a key in the object passed into iterate()
    // return its value
    if (target.length === 0 && obj[tmp]) return out = obj[tmp];

    // if the key exists in the object passed into iterate()
    // but it is an object, run iterate() with that object
    // and the reduced target array
    if (obj[tmp] && typeof obj[tmp] === 'object') iterate(obj[tmp], target);

    return;
  }(obj, target));

  return out;
}

findDeepProp(doc, 'send.thing.fullname.first') // Bob
findDeepProp(doc, 'send.thing.fullname.last') // Smith

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM