Что я могу использовать вместо typeof в JS

Если у меня есть массив javascript с объектами внутри, что-то вроде этого

articlesParams[itemId].properties.loaded

Если я попытаюсь сделать это:

if ( typeof articlesParams[itemId].properties.loaded != 'undefined' && ...) {
    // do something...
}

Я столкнулся с проблемой, что если articleParams[itemId].properties не определено, я получаю сообщение об ошибке: Невозможно прочитать свойства неопределенного свойства.

Так что в этом случае я должен сделать что-то глупое, например:

if ( typeof articlesParams[itemId].properties != 'undefined' &&  
        typeof articlesParams[itemId].properties.loaded != 'undefined'  && ...) {
    // do something...
}

Есть ли эквивалент в javascript, например, в PHP isset()?


person Sergey Onishchenko    schedule 06.03.2014    source источник
comment
Да, есть эквивалент, typeof articlesParams[itemId].properties == 'undefined'.   -  person Rudi Visser    schedule 06.03.2014
comment
В проекте phpjs есть реализация isset для Javascript. Если это действительно то, чего вы хотите.   -  person Xotic750    schedule 06.03.2014
comment
Похоже, вы на самом деле получаете сообщение об ошибке, потому что articlesParams[itemId] не определено, а не потому, что properties не определено.   -  person JLRishe    schedule 06.03.2014
comment
Извините, ребята, я нашел опечатку в своем вопросе: articleParams[itemId].properties == 'undefined' должно быть: articleParams[itemId].properties != 'undefined' (уже исправлено)   -  person Sergey Onishchenko    schedule 06.03.2014
comment
Но вопрос все тот же и не решен   -  person Sergey Onishchenko    schedule 06.03.2014


Ответы (3)


Альтернативой было бы просто сделать это, что довольно типично для JS:

if (articlesParams[itemId] &&
    articlesParams[itemId].properties &&  
    articlesParams[itemId].properties.loaded  && ...) {
    // do something...
}

или это:

var item = articlesParams[itemId];
if (item && item.properties && item.properties.loaded  && ...) {
    // do something...
}

Следует отметить, что это не сработает, если вы хотите, чтобы инструкция if выполнялась, даже если loaded равно false. В этом случае вам лучше проверить, является ли это undefined, используя typeof.

person JLRishe    schedule 06.03.2014
comment
И если item это undefined, что делает item.properties? - person Xotic750; 06.03.2014
comment
@ Xotic750 Это приведет к ошибке. Если есть вероятность, что оно может быть неопределенным, вы также можете добавить item к условию if. - person JLRishe; 06.03.2014
comment
Да, это была просто заметка, как сказал ОП Cannot read property 'properties' of undefined.;) - person Xotic750; 06.03.2014
comment
@ Xotic750 Понятно. Хороший улов. :) - person JLRishe; 06.03.2014
comment
Еще одно замечание по поводу примечания: возможно, используйте положительную проверку вместо проверки undefined, затем выполните if (item && item.properties && item.properties.loaded === true && ...) { или что-то подобное === false, в зависимости от того, что соответствует условию. - person Xotic750; 06.03.2014

Несмотря на многословие, стандартная идиома JavaScript для проверки того, является ли переменная неопределенной, использует typeof и на самом деле очень похоже на то, что вы написали. Не существует отдельного JavaScript-эквивалента PHP isset().

Всего два незначительных улучшения:

Как это:

var item = articlesParams[itemId];
if (typeof item !== 'undefined') {
   var props = item.properties;
   if (typeof props !== 'undefined') {
       var loaded = props.loaded;
       if (typeof loaded !== 'undefined') {
           // do something...
       }
   }
}

Конечно, если loaded, props и т. д. не используются повторно, мало мотивации для определения переменных для них.

person kjhughes    schedule 06.03.2014

Как все говорили, вы можете просто связать множество выражений typeof. В качестве альтернативы....

var result;
try {
   result=typeof articlesParams[itemId].properties.loaded;
} catch(e) {
   result='undefined';
}
if ('undefined'==result) {
    // do something
}

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

Возможно, будет более подходящим просто сделать это:

try {
   typeof articlesParams[itemId].properties.loaded;
} catch (e) {
   // do something
}
person symcbean    schedule 06.03.2014
comment
Хотя я делаю такие вещи при обнаружении функций/ошибок, я не думаю, что буду использовать их в основном выполнении моего кода. Но решение. :) - person Xotic750; 06.03.2014
comment
try{typeof a.b.c.d.e.f} catch(e){'undefined'} — это никогда не вызовет исключения и кажется самым кратким способом увидеть, существует ли глубокий объект. Если объект не существует, он всегда будет возвращать «неопределенный» - person Terry Riegel; 18.04.2015