Get a nested property of a complex object at any level of depth
You can take advantage of the JSON.stringify's replacer argument.
This way it becomes much more simple:

var app =
  findProperty: function(data, name) {
    var result = {
      isFound: false,
      value: null
    };
    JSON.stringify(data, function(k, v) {
      if (k == name) {
        result.isFound = true;
        result.value = v;
        return undefined; // stop stringification
      } else {
        return v; // continue with same value
      }
    });
    return result;
  }
}


Compared to your original function, there are two points to consider:


one little caveat is that a Date object is returned stringified, e.g. for a15 in your dataexample:


has an original value of new Date.
is returned as Date {Thu Jan 14 2016 18:34:10 GMT+0100} by your function.
is returned as 2016-01-14T17:34:10.220Z by the mine.

your function excludes Array objects, while the mine processes them, e.g. calling app.findProperty(data, '0') will return red (from a6: ['red', 'blue', true] in your dataexample).


My version seems to be faster (approximatively x2) using your data example, but it's not certain how it'll be in any case.

The snippet below tries to illustrate it, simultaneously controlling the results between the two versions:



var data = {
  a: {
    a1: 'hello',
    a2: true,
    a3: false,
    a4: {},
    a5: [],
    a6: ['red', 'blue', true],
    a61: {a61a: 'red', a61b: 'blue'},
    a7: null,
    a8: undefined,
    a9: NaN,
    a10: function() {},
    a11: Math,
    a12: JSON,
    a13: /a-z/,
    a14: new ReferenceError,
    a15: new Date,
    a16: new Number(7),
    a17: new String("abc"),
    a18: new Boolean(true)
  },
  b: {
    b1: {
      b1a: true,
      b1b: 100
    },
    b2: {
      b2a: true,
      b2b: false,
      b2c: 10.10
    }
  }
}

var app = {
  findProperty: function(data, name) {
    var toType = function(obj) {
      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    };
    var data = data,
      process = true,
      result = {
        isFound: false,
        value: null
      };
    var recursion = function(data, name) {
      var type = toType(data);
      if (type === 'object') {
        Object.keys(data).forEach(function(property) {
          if (process) {
            if (name in data) {
              process = false;
              result.isFound = true;
              result.value = data[name];
            } else if (typeof data[property] === 'object') {
              recursion(data[property], name);
            }
          }
        });
      }
    };
    recursion(data, name);
    return result;
  },

  findProp: function(data, name) {
    var result = {
      isFound: false,
      value: null
    };
    JSON.stringify(data, function(k, v) {
      if (k == name) {
        result.isFound = true;
        result.value = v;
        return undefined; // stop stringification
      } else {
        return v; // continue with same value
      }
    });
    return result;
  }
}

var names = [
  'a', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a61', 'a61a', 'a7', 'a8', 'a9',
  'a10', 'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 'a17', 'a18',
  'b', 'b1', 'b2', 'b1a', 'b1b', 'b2a', 'b2b', 'b2c', 'xxx', 'yyy'
];
var results = {};

function exec(func) {
  results[func] = [];
  begTime = Date.now();
  for (var i = 0, n = names.length; i &lt; n; i++) {
    var name = names[i],
        result = app[func](data, name);
    results[func][i] = result.value;
    console.log(name, result.isFound, result.value);
  }
  console.log(
    '--- using ', func + ':', (Date.now() - begTime) + 'ms');
}

console.clear();
exec('findProperty');
exec('findProp');
for (var i = 0, n = results.findProperty.length; i &lt; n; i++) {
  if (results.findProperty[i] !== results.findProp[i]) {
    console.log(
      '*** Error in ' + i + ':',
      results.findProperty[i], '&lt;--&gt;', results.findProp[i]
    );
  }
}




Apart from the already mentioned Date difference, you'll see an "error" on the NaN value: this is normal since NaN is equal to nothing, even itself.