Проверка существования вложенного ключа объекта JavaScript - PullRequest
553 голосов
/ 13 апреля 2010

Если у меня есть ссылка на объект:

var test = {};

, который потенциально (но не сразу) будет иметь вложенные объекты, что-то вроде:

{level1: {level2: {level3: "level3"}}};

Как лучше всегопроверить наличие свойства в глубоко вложенных объектах?

alert(test.level1); дает undefined, но alert(test.level1.level2.level3); не удается.

В настоящее время я делаю что-то вроде этого:

if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
    alert(test.level1.level2.level3);
}

но мне было интересно, есть ли лучший способ.

Ответы [ 53 ]

0 голосов
/ 05 июня 2017

Самый лучший и простой ответ:

var isDefinedPath = function (path) {

    var items = path.split ('.');

    if (!items || items.length < 1 || !(items[0] in window)) { return false; }

    var buffer = [items[0]];
    for (var i = 1, e = items.length; i < e; i ++) {
        buffer.push (items[i]);
        if (eval ('typeof(' + buffer.join ('.') + ') == "undefined"')) {
            return false;
        }
    }

    return true;

}

тест: isDefinedPath ('level1.level2.level3');

первый уровень не может быть массивом, другие могут

0 голосов
/ 02 июля 2019

И еще один, очень компактный:

function ifSet(object, path) {
  return path.split('.').reduce((obj, part) => obj && obj[part], object)
}

называется:

let a = {b:{c:{d:{e:'found!'}}}}
ifSet(a, 'b.c.d.e') == 'found!'
ifSet(a, 'a.a.a.a.a.a') == undefined

Он не будет работать замечательно, поскольку разделяет строку (но повышает читаемость вызова) и выполняет итерации по всему, даже если уже очевидно, что ничего не будет найдено (но повышает читаемость самой функции).

как минимум быстрее _.get http://jsben.ch/aAtmc

0 голосов
/ 18 ноября 2014

Я написал библиотеку с именем l33teral для проверки вложенных свойств . Вы можете использовать это так:

var myObj = {/*...*/};
var hasNestedProperties = leet(myObj).probe('prop1.prop2.prop3');

Мне тоже здесь нравятся решения ES5 / 6.

...