Я получаю следующую ошибку, когда проверяю длину массива. Какой подход будет правильным?
main.js
if (drugPrice.mailPrice.rejectMessage.length !== 0 && Array.isArray(drugPrice.mailPrice.rejectMessage)) {
//code goes here
}
Ошибка
TypeError: Cannot read property 'length' of undefined
поменять местами чеки... if ( isArray && arr.length )... код выполняется в том порядке, в котором он читается. если нет массива, нет длины, поэтому ошибка.
Массив может существовать, если длина === 0, а также
иногда я получаю пустой массив, поэтому мне нужно проверить длину
Попробуйте поменять порядок проверок:
if (Array.isArray(drugPrice.mailPrice.rejectMessage) && drugPrice.mailPrice.rejectMessage.length !== 0) {
code goes here
}
Проверьте свои данные, замена условия может помочь, но не предотвратит возникновение некоторых ошибок. Например, Array.isArray(drugPrice.mailPrice.rejectMessage)
выдаст ошибку, если drugPrice.mailPrice
не определено.
if (drugPrice.mailPrice
&& drugPrice.mailPrice.rejectMessage
&& drugPrice.mailPrice.rejectMessage.length !== 0
&& Array.isArray(drugPrice.mailPrice.rejectMessage)) {
// code goes here
}
var drugPrice = { mailPrice: { rejectMessage: {} } };
if (drugPrice.mailPrice
&& drugPrice.mailPrice.rejectMessage
&& drugPrice.mailPrice.rejectMessage.length !== 0
&& Array.isArray(drugPrice.mailPrice.rejectMessage)) {
console.info('success');
} else {
console.info('fail')
}
ПРИМЕЧАНИЕ
Всегда проверяйте свои данные. Не думайте, что вы всегда будете получать правильные данные. При работе с объектами всегда проверяйте их, так как выполнение data.name
может сломать ваше приложение, если data
имеет значение null или не определено. например, для следующего объекта.
const drugPrice = { mailPrice: null };
делает, выдает ошибку.
const drugPrice = { mailPrice: null };
// throws an error, Cannot read property 'rejectMessage' of undefined
if (Array.isArray(drugPrice.mailPrice.rejectMessage)) {
}
чтобы этого не произошло, нам нужно проверить, существует ли свойство, как показано ниже.
const drugPrice = { mailPrice: null };
console.info(drugPrice.mailPrice && Array.isArray(drugPrice.mailPrice.rejectMessage) || 'Price is null or undefined')
Хотя вы делаете правильные выводы, это упускает фактическую проблему в исходном коде и, следовательно, неверно. Попробуйте -> var drugPrice = { mailPrice: { rejectMessage: {} } };
может я что-то упускаю jsbin.com/xabuwibavu/edit?js,консоль
На самом деле извините - беру обратно. Я не понимаю, почему этот код не выдает ошибку в rejectMessage.length
, если rejectMessage
не является массивом (или строкой).
он не выдает, потому что rejectMessage
существует и является объектом.
Это предположение с моей стороны, вероятно, сформированное из моей привычки всегда ставить .isArray()
перед проверкой длины. Я приношу извинения. Если отредактировать ваш ответ, я могу удалить свой неправильный отрицательный голос.
Все в порядке, я проверяю объекты, прежде чем что-либо с ними делать.
Конечно. Просто мы делаем это по-разному и меня это сбило :)
Вам действительно не нужно на самом деле делать .length !== 0
. Вы можете просто сделать:
if (Array.isArray(A.B.C) && A.B.C.length) { // <-- order is important here
//...
}
.length
будет оцениваться как логическое значение, и это даст вам тот же результат, что и проверка с помощью !==0
При этом, однако, ваши пути довольно длинные, поэтому вы, вероятно, захотите убедиться, что они действительны. Это означает, что если drugPrice
или mailPrice
ложны, у вас возникнет проблема. Поэтому обычно вы также хотели бы проверить их. Поскольку ваш вопрос был о части массива, я пропущу их, но только для вашего сведения.
Вы можете создать свою собственную проверку пути или, если вы используете библиотеки, такие как lodash/underscore и т. д., у них всегда есть удобные функции get/has
для проверки, как это (с lodash
):
if (_.has(drugPrice, 'mailPrice.rejectMessage.length'))
//...
}
Очевидно, не используйте эти библиотеки только для этого, но если они у вас уже есть, эти методы весьма удобны. Вы также можете просто проверить каждый из путей через:
if (A && A.B && Array.isArray(A.B.C) && A.B.C.length) {
//...
}
Это просто становится утомительным, если у вас длинные пути к объектам и т. д.
Проблема в вашем коде заключается в том, что javascript проверяет длину массива, прежде чем проверять, является ли массив типом массива. Вы должны изменить порядок в операторе if.
Вы можете попробовать с:
if (myArr && Array.isArray(myArr) && myArr.length !== 0) {
// your code
}
Теперь код выполняется в правильном порядке.
Второе условие проверяет, является ли myArr типом Array, вы также можете сделать это так:
если (myArr && myArr.push && myArr.length !== 0) { // ваш код }
Третье условие проверяет, не является ли myArr пустым.
Снимите проверку длины. Сделанный.