Access object child properties using a dot notation string [duplicate]

I'm temporarily stuck with what appears to be a very simple JavaScript problem, but maybe I'm just missing the right search keywords!

Say we have an object

var r = { a:1, b: {b1:11, b2: 99}};

There are several ways to access the 99:

r.b.b2
r['b']['b2']

What I want is to be able to define a string

var s = "b.b2";

and then access the 99 using

r.s or r[s] //(which of course won't work)

One way is to write a function for it that splits the string on dot and maybe recursively/iteratively gets the property. But is there any simpler/more efficient way? Anything useful in any of the jQuery APIs here?


Here's a naive function I wrote a while ago, but it works for basic object properties:

function getDescendantProp(obj, desc) {
    var arr = desc.split(".");
    while(arr.length && (obj = obj[arr.shift()]));
    return obj;
}

console.log(getDescendantProp(r, "b.b2"));
//-> 99

Although there are answers that extend this to "allow" array index access, that's not really necessary as you can just specify numerical indexes using dot notation with this method:

getDescendantProp({ a: [ 1, 2, 3 ] }, 'a.2');
//-> 3

split and reduce while passing the object as the initalValue

var r = { a:1, b: {b1:11, b2: 99}};
var s = "b.b2";

var value = s.split('.').reduce(function(a, b) {
  return a[b];
}, r);

console.log(value);

Update (thanks to comment posted by TeChn4K)

With ES6 syntax, it is even shorter

var r = { a:1, b: {b1:11, b2: 99}};
var s = "b.b2";

var value = s.split('.').reduce((a, b) => a[b], r);

console.log(value);

You can use lodash get() and set() methods.

Getting

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

Setting

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// → 4

If it's possible in your scenario that you could put the entire array variable you're after into a string you could use the eval() function.

var r = { a:1, b: {b1:11, b2: 99}};
var s = "r.b.b2";
alert(eval(s)); // 99

I can feel people reeling in horror