Почему возникает ошибка: Uncaught TypeError: Cannot read property of undefined or null (reading ***)

Периодически, при разработке на JavaScript возникает ошибка: Cannot read property *** of undefined или Cannot read property *** of null

Например в этом коде:

const count = result.data.length;

Cannot read property of undefined (reading 'length')

Или в этом:

const dataMap = response.lines.map(item => item * 2);

Uncaught TypeError: Cannot read properties of undefined (reading 'map')

Как понять причину ошибки, что оно означает, почему появляются и как ее исправить?


Ответы (1 шт):

Автор решения: SwaD

Рассматривать будем на примере данного объекта

const data = {
    name: 'TypeError',
    message: '',
    errors: null,
    sayHi: function() {
        console.log(this.name)
    }
}

Cannot read property of undefined or null

Ошибка возникнет, если мы попытаемся выполнить следующий код:

data.errors.forEach(item => console.log(item)); // null.forEach()

Uncaught TypeError: Cannot read properties of null (reading 'forEach')

data.values.map(item => console.log(item)); // undefined.map()

Uncaught TypeError: Cannot read properties of undefined (reading 'map')

Данные ошибки говорят нам о том, что мы пытаемся вызвать методы у ничего(null или undefined).
data.errors это null. У null нет методов. А data.values вообще не существует. Нельзя вызвать метод у того, что не существует.

Так же, если объявить переменную и попытаться вызвать у нее какой либо метод без инициализации, то получим ошибку(в данном случае Cannot read properties of undefined (reading 'push')):

const arr;
arr.push(1); // undefined.push();

Cannot read property

of undefined - ключ не определен, т.е. отсутствует в объекте.
of null - ключ в объекте есть, но имеет значение null. У null нет методов.

Как этого избежать?

Проверять, что приходит в объекте и существуют ли в объекте нужные нам значения. Один из вариантов проверки, воспользоваться console.log().
Можно начать с последнего ключа, однако лучше весь пусть вывести, что бы понимать структуру, с которой работаем:

console.log(data) // { name: 'TypeError', message: '', errors: null, sayHi: [Function] }
console.log(data.errors) // null

Так же можно воспользоваться оператором необязательной цепочки вызовов '?.'

const a = data?.errors?.forEach(item => console.log(item)); // null.forEach()
const b = data?.values?.map(item => console.log(item)); // undefined.map()

Оператор необязательной цепочки вызовов будет проверять значение слева. Если значение null или undefined, цепочка прерывается и возвращается значение undefined.

Для объявленных переменных указывать тип данных

const arr = []; // Указываем, что меременная это массив
arr.push(1); // Можем воспользоваться любым методом массива;
→ Ссылка