Я провел тесты производительности (спасибо cdMinix за добавление lodash) для некоторых предложений, предложенных по этому вопросу, с результатами, перечисленными ниже.
Отказ от ответственности # 1 Превращение строк в ссылки - это ненужное метапрограммирование и, вероятно, его лучше избегать. Не забывайте свои ссылки для начала. Узнайте больше из этого ответа на похожий вопрос .
Отказ от ответственности # 2 Мы говорим о миллионах операций в миллисекунду здесь. Маловероятно, что какой-либо из них будет иметь большое значение в большинстве случаев использования. Выберите тот, который имеет больше смысла, зная ограничения каждого из них. Для меня я бы пошел с чем-то вроде reduce
из-за удобства.
Обтекание объекта (Оливер Стил) - 34% - самый быстрый
var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
var r2 = (((test || {}).level1 || {}).level2 || {}).foo;
Исходное решение (предлагается в вопросе) - 45%
var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;
checkNested - 50%
function checkNested(obj) {
for (var i = 1; i < arguments.length; i++) {
if (!obj.hasOwnProperty(arguments[i])) {
return false;
}
obj = obj[arguments[i]];
}
return true;
}
get_if_exist - 52%
function get_if_exist(str) {
try { return eval(str) }
catch(e) { return undefined }
}
validChain - 54%
function validChain( object, ...keys ) {
return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
}
objHasKeys - 63%
function objHasKeys(obj, keys) {
var next = keys.shift();
return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
}
nestedPropertyExists - 69%
function nestedPropertyExists(obj, props) {
var prop = props.shift();
return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
}
_. Get - 72%
самый глубокий - 86%
function deeptest(target, s){
s= s.split('.')
var obj= target[s.shift()];
while(obj && s.length) obj= obj[s.shift()];
return obj;
}
грустные клоуны - 100% - самые медленные
var o = function(obj) { return obj || {} };
var r1 = o(o(o(o(test).level1).level2).level3);
var r2 = o(o(o(o(test).level1).level2).foo);