Подтвердить что ты не робот

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

Мне нужно проверить свойство глубоко вложенных объектов, такое как YAHOO.Foo.Bar.xyz.

Используемый мной код

if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
    // operate on YAHOO.Foo.Bar.xyz
}

Это работает, но выглядит неуклюжим.

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

4b9b3361

Ответ 1

Если вы ожидаете, что YAHOO.Foo.Bar будет действительным объектом, но хотите сделать ваш код пуленепробиваемым на всякий случай, если это не так, тогда может быть самым чистым, просто попробуйте поймать его и пусть один обработчик ошибок поймает отсутствующий сегмент. Затем вы можете просто использовать одно условие if вместо четырех, которое обнаружит, существует ли свойство терминала и обработчик catch, чтобы поймать вещи, если промежуточные объекты не существуют:

try {
    if (YAHOO.Foo.Bar.xyz) {
        // operate on YAHOO.Foo.Bar.xyz
} catch(e) {
    // handle error here
}

или, в зависимости от того, как работает ваш код, это может быть просто:

try {
    // operate on YAHOO.Foo.Bar.xyz
} catch(e) {
    // do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}

Я особенно использую их при работе с иностранными вводами, которые должны быть определенного формата, но недопустимый ввод - это возможность, которую я хочу поймать и обработать самостоятельно, а не просто позволить распространению исключения вверх.

В общем, некоторые разработчики javascript недоиспользуют try/catch. Я нахожу, что иногда я могу заменить 5-10, если утверждения проверяют ввод с помощью одного try/catch вокруг большего функционального блока и делают код намного проще и читабельнее в одно и то же время. Очевидно, что, когда это уместно, зависит от конкретного кода, но это определенно стоит рассмотреть.

FYI, если обычная операция заключается в том, чтобы не генерировать исключение с помощью try/catch, это может быть намного быстрее, чем куча операторов if.


Если вы не хотите использовать обработчик исключений, вы можете создать функцию для проверки любого произвольного пути для вас:

function checkPath(base, path) {
    var current = base;
    var components = path.split(".");
    for (var i = 0; i < components.length; i++) {
        if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
            return false;
        }
        current = current[components[i]];
    }
    return true;
}

Пример использования:

var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
    // a.b.c.d exists and can be safely accessed
}

Ответ 2

var _ = {};

var x = ((YAHOO.Foo || _).Bar || _).xyz;

Ответ 3

Рассмотрим эту служебную функцию:

function defined(ref, strNames) {
    var name;
    var arrNames = strNames.split('.');

    while (name = arrNames.shift()) {        
        if (!ref.hasOwnProperty(name)) return false;
        ref = ref[name];
    } 

    return true;
}

Использование:

if (defined(YAHOO, 'Foo.Bar.xyz')) {
    // operate on YAHOO.Foo.Bar.xyz
}

Live demo: http://jsfiddle.net/DWefK/5/

Ответ 4

Если вам нужно проверить правильность пути, а не существование члена "xyz" на объекте "YAHOO.Foo.Bar", вероятно, будет проще всего перевести вызов в try catch:

var xyz;
try {
    xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
    // fail;
};

В качестве альтернативы вы можете использовать строку string-kong-fu-magic TM:

function checkExists (key, obj) {
    obj = obj || window;
    key = key.split(".");

    if (typeof obj !== "object") {
        return false;
    }

    while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ;

    return (!key.length && typeof obj !== "undefined");
}

Используется следующим образом:

if (checkExists("YAHOO.Foo.Bar.xyz")) {
    // Woo!
};

Ответ 5

Эта проблема решена довольно красиво с помощью coffeescript (который компилируется до javascript):

if YAHOO.Foo?.Bar?.xyz
  // operate on YAHOO.Foo.Bar.xyz

Ответ 6

используйте try catch.

a={
  b:{}
};

//a.b.c.d?true:false; Errors and stops the program.

try{
  a.b.c.d;
}
catch(e){
  console.log(e);//Log the error
  console.log(a.b);//This will run
}