Javascript "Невозможно прочитать длину" свойства "undefined" при проверке переменной длины - программирование

Javascript "Невозможно прочитать длину" свойства "undefined" при проверке переменной длины

Я строю скребок node, который использует cheerio для разбора DOM. Это больше или вопрос ванильного JavaScript, хотя. В одной части моей работы я загружаю некоторый контент в переменную, затем проверяю переменную length, например так:

var theHref = $(obj.mainImg_select).attr('href');
if (theHref.length){
   // do stuff
} else {
  // do other stuff
}

Это прекрасно работает, пока я не наткнулся на URL, для которого $(obj.mainImg_select).attr('href') не существует. Я предполагал, что моя проверка theHref.length будет учитывать это и перейти к выражению else: do other stuff, но вместо этого я получил:

TypeError: Cannot read property 'length' of undefined

Что я здесь не так делаю и как мне это исправить?

4b9b3361

Ответ 1

Вы можете проверить, что theHref определяется путем проверки на undefined.

if (undefined !== theHref && theHref.length) {
    // `theHref` is not undefined and has truthy property _length_
    // do stuff
} else {
    // do other stuff
}

Если вы хотите также защитить себя от значений false, таких как null, тогда проверьте theHref правду, которая немного короче

if (theHref && theHref.length) {
    // `theHref` is truthy and has truthy property _length_
}

Ответ 2

Почему?

Вы спросили, почему это происходит, давайте посмотрим:

Официальный язык диктует вызов внутреннего метода [[GetValue]]. Ваш .attr возвращает неопределенное значение, и вы пытаетесь получить доступ к его длине.

If Type(V) is not Reference, return V.

Это действительно так, поскольку undefined не является ссылкой (наряду с null, number, string и boolean)

Пусть base будет результатом вызова GetBase (V).

Это получает undefined часть myVar.length.

Если IsUnresolvableReference (V), сгенерировать исключение ReferenceError.

Это не так, поскольку оно разрешимо и разрешается как неопределенное.

Если IsPropertyReference (V), то

Это происходит потому, что это ссылка на свойство с синтаксисом ..

Теперь он пытается преобразовать undefined в функцию , что приводит к ошибке TypeError.

Ответ 3

Существует разница между пустой строкой "" и переменной undefined. Вы должны проверить, содержит ли Href определенную строку, а не ее длину:

if(theHref){
   // ---
}

Если вы все еще хотите проверить длину, сделайте следующее:

if(theHref && theHref.length){
   // ...
}

Ответ 4

В дополнение к другим предложениям есть еще один вариант для решения этой проблемы.

Если ваше приложение должно вести себя одинаково в случае отсутствия атрибута "href", так как в случае его отсутствия просто замените это:

var theHref = $(obj.mainImg_select).attr('href');

с этим:

var theHref = $(obj.mainImg_select).attr('href') || '';

который будет обрабатывать пустую строку ('') по умолчанию, если атрибут не найден.

Но это действительно зависит от того, как вы хотите обрабатывать атрибут undefined "href". Этот ответ предполагает, что вы захотите обработать его, как если бы это была пустая строка.

Ответ 5

Если вы не выполняете какое-то числовое сравнение свойства length, лучше не использовать его в инструкции if, просто выполните:

if(theHref){
   // do stuff
}else{
  // do other stuff
}

Пустая (или undefined, как в этом случае) строка будет оцениваться как false (точно так же, как и длина нуля.)

Ответ 6

Как было сказано в другом месте, ссылка на свойство .length не работает, поскольку theHref - undefined. Однако имейте в виду любое решение, которое предполагает сравнение theHref с undefined, которое не является ключевым словом в JavaScript и может быть переопределено.

Для полного обсуждения проверки переменных undefined см. Обнаружение свойства объекта undefined и, в частности, первого ответа.

Ответ 7

Вы можете просто проверить, является ли длина элемента неопределенной или нет, просто используя

var theHref = $(obj.mainImg_select).attr('href');
if (theHref){
   //get the length here if the element is not undefined
   elementLength = theHref.length
   // do stuff
} else {
   // do other stuff
}