Function that helps with reaching nested objects /**
 * Returns the value of a nested property of source object if it exists.
 * Even if the nested property evaluates to false it will be returned.
 * If the nested property does not exist, undefined will be returned.
 * @param {Object} source       source object
 * @param {String} path         path without first dot e.g. "response.http.statusCode"
 * @param {String=} sourceName  if provided, any catched error will be logged to console
 * @returns {*}                 value under the source.path or undefined
 */
function reach(source, path, sourceName) {
    var result;
    try {
        if (sourceName) {
            eval('var ' + sourceName + '=source; result=' + sourceName + '.' + path);
        } else {
            eval('result=source.' + path);
        }
    } catch (err) {
        if (sourceName) {
            console.log(err);
        }
    }
    return result;
}


I know that eval is dangerous, but I made the assumption that it's the caller's responsibility.
Very similar to an earlier answer I did with regards to deep value extraction. Here's the code:

function createResolver(keypath){
  return new Function('root', `
    try { return root.${keypath}; }
    catch(e){ return undefined; }
 `);
}

// Return foo.bar.baz
var obj1 = { foo: { bar: { baz: 'bam!!!' }}};
var resolver1 = createResolver('foo.bar.baz');
var value1 = resolver1(obj1);


One difference between this one and your approach is that your approach seems to evaluate on every call. This can be slow as you are having the browser evaluate the string JavaScript on every call. A constructed function on the other hand can be cached. This means you can construct the function once, store the constructed function, and call it over and over again without having to re-evaluate the string every time.

// keypath-resolver store
var resolvers = {}

function createResolver(keypath){
  return new Function('root', `
    try { return root.${keypath}; }
    catch(e){ return undefined; }
 `);
}

// Create a resolver for foo.bar.baz. We only have JS evaluate the string here.
resolvers['foo.bar.baz'] = createResolver('foo.bar.baz');

var obj1 = { foo: { bar: { baz: 'bam!!!' }}};
var obj2 = { foo: { bar: { baz: 'pow!!!' }}};

// We just call the function. No evaluation!
resolvers['foo.bar.baz'](obj1);
resolvers['foo.bar.baz'](obj2);


Although these two approaches seem to act the same, one issue with eval is that it evaluates the string in the scope it is called. This means it can leak variables or override code that's visible in the current scope, just like you did with result. A generated function on the other hand does not. It does not form a closure of the scope it was created from, and the immediate outer scope is the global scope. This makes it relatively safer than eval.

Your reliance of console.log is also something to ponder on. If it's an error, is it not better to actually throw than just log the error? Also, if the keypath isn't fully resolved, this means the value isn't present which makes it technically undefined. Consider returning undefined instead of logging an error if you want errors to be handled.