в javascript есть ли синтетические ярлыки, проверяющие существование каждого слоя внедренного объекта? - PullRequest
1 голос
/ 10 июня 2011
Например,

, следующий код

  if( obj.attr1.attr2.attr3.attr4 == 'constant' ) return;

необходимо переписать как

  if( obj.attr1 
      && obj.attr1.attr2 
      && obj.attr1.attr2.attr3
      && obj.attr1.attr2.attr3.attr4 == 'constant' ) return;

. Правильно ли я в том, что каждый слой необходимо тестировать индивидуально, или есть синтаксическийярлык для этого?

если бы это был однократный выстрел, это не было бы проблемой, но эта конструкция пронизывает мой код.

из ответов, вот решение, которое я нашел на месте:

try{ if( obj.attr1.attr2.attr3.attr4 != 'const' ) throw 'nada'; } catch(e){
    nonblockAlert( 'Relevant Message' );
    return;
};

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

Ответы [ 5 ]

3 голосов
/ 10 июня 2011

Там нет реального ярлыка. Вы можете написать вспомогательную функцию, которая сделает это за вас, что может сгущаться до:

function getProp(obj){
    var i=0, l=arguments.length;
    while(i<l && (obj = obj[arguments[i++]]));
    return obj;
}
if( getProp(obj, 'attr1', 'attr2', 'attr3', 'attr4') == 'constant')

или вы можете сделать:

var tmp;
if((tmp = obj.attr1)
    && (tmp=tmp.attr2)
    && (tmp=tmp.attr3)
    && (tmp.attr4 == 'constant')) {
2 голосов
/ 10 июня 2011

Как уже упоминали люди, но никто не сделал, вы можете использовать try / catch:

try {
    if(obj.attr1.attr2.attr3.attr4 == 'constant') return;
} catch(e) {}

Это не самый лучший код, но он самый лаконичный и легко читаемый. Лучший способ избежать этого - не вкладывать так глубоко в дерево потенциально отсутствующих объектов.

2 голосов
/ 10 июня 2011

Интересный вопрос - хотя у меня никогда не было этой проблемы. Лучшая альтернатива, которую я могу придумать, - написать вспомогательную функцию:

function get(chain, context) {
   var o = arguments.length == 2 ? context : window,
       c = chain.split('.');
   for (var i = 0; i < c.length; i++) {
       if (!o) return null;
       o = o[c[i]];
   }
   return o;
}

Если obj является глобальным, то вы можете сделать что-то вроде:

if (get('obj.attr1.attr2.attr3.attr4') == 'constant') return;

В противном случае:

if (get('attr1.attr2.attr3.attr4', obj) == 'constant') return;
0 голосов
/ 10 июня 2011

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

function getThis(string){
    var N= string.split('.'), O= this[N.shift()];
    while(O && N.length) O= O[N.shift()];
    return O;
}


window.obj={
    attr1:{
        attr2:{
            attr3:{
                attr4: 'constant!'
            }
        }
    }
}

getThis ('obj.attr1.attr2.attr3.attr4');

/ * возвращаемое значение: (строка) ' константа! ' * /

getThis.call (obj, 'attr1.attr2.attr3.attr4 ');

/ * возвращаемое значение: (строка)' константа! '* /

0 голосов
/ 10 июня 2011

Нет, к сожалению, нет, за исключением использования try/catch. Вы могли бы, однако, написать себе вспомогательную функцию (не проверено, но концепция есть):

function existsAndEquals(obj, layers, compare) {

    for (var i = 0; i < layers.length; i++)
        if (!(obj = obj[layers[i]]))
            return false;

    return obj == compare;

}

if (existsAndEquals(obj, ['attr1', 'attr2', 'attr3', 'attr4'], 'constant'))
    // ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...