javascript エラー「Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’)」の解決方法

javascript エラー「Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’)」の解決方法

javascriptで、エラー「Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’)」が発生した場合の原因と解決方法を記述してます。主に定義されていない値を使用した際に発生します。日本語だと「undefinedに対してxxxプロパティは読み込むことができません」という意味になります。

環境

  • OS windows11 pro 64bit
  • Apache 2.4.43
  • ブラウザ chrome 108.0.5359.72

エラー内容

以下の、インデックス番号を指定して配列のデータを文字列化しようとしたコードを実行時に発生。
※その他のエラーは後述してます。

const arr = [0, 1, 2];

console.log(arr[3].toString()); // エラー発生

エラーメッセージ

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

画像

firefox(バージョン107)では、下記のエラーとなります。

Uncaught TypeError: arr[3] is undefined

画像

原因

存在しない配列の要素のインデックス番号を指定しているため。

解決方法

存在するものを指定する。

const arr = [0, 1, 2];

console.log(arr[2].toString()); // 2

または、判定してから使用します。

const arr = [0, 1, 2];

// undefinedであるかを判定してから使用
if(typeof arr[3] !== "undefined"){

  console.log(arr[3].toString());

}

ちなみに、存在しない場合は、別の値を返したい場合は以下のように「Null 合体演算子」を使用することもできます。

const arr = [0, 1, 2];

console.log( (arr[3] ?? 'nothing').toString() ); // nothing

console.log( (arr[2] ?? 'nothing').toString() ); // 2

その他のエラー

空の配列にpush

以下のように、空の配列を生成後にインデックス番号を指定して「push」した場合も発生します。

const arr = [];

arr[0].push('aaa'); // Uncaught TypeError: Cannot read properties of undefined (reading 'push')

console.log(arr);

解決方法

インデックス番号は指定しない。

const arr = [];

arr.push('aaa');

console.log(arr); // ['aaa']

「HTMLCollection」

以下の新しいクラスを追加するコードでも発生します。

<div class="box">Box1</div>
<div class="box">Box2</div>
<div class="box">Box3</div>

<script>

const elems = document.getElementsByClassName('box');

elems.classList.add('new');
// Uncaught TypeError: Cannot read properties of undefined (reading 'add')

</script>

解決方法

原因は「HTMLCollection」に対して「classList.add」を、そのまま指定しているためです。
指定する位置を指定するか、

<div class="box">Box1</div>
<div class="box">Box2</div>
<div class="box">Box3</div>

<script>

const elems = document.getElementsByClassName('box');

console.log(elems);
// HTMLCollection(3) [div.box, div.box, div.box]

elems[0].classList.add('new');

</script>

全てに適応するのであれば、配列化して全ての要素1つ1つに適応します。

<div class="box">Box1</div>
<div class="box">Box2</div>
<div class="box">Box3</div>

<script>

const elems = document.getElementsByClassName('box');

[...elems](v => {

  v.classList.add('new');

});

</script>

オブジェクトのプロパティ

ネストされたオブジェクトのプロパティを直接指定したり、

const obj = {a: {b:[10,11],c:[20,22]}, d: [30,31]};

console.log(obj.b); // undefined

console.log(obj.b.length);
// Uncaught TypeError: Cannot read properties of undefined (reading 'length')

存在しないオブジェクトのプロパティを指定しても同じエラーが発生します。

const obj = {a: {b:[10,11],c:[20,22]}, d: [30,31]};

console.log(obj.f); // undefined

console.log(obj.f.length);
// Uncaught TypeError: Cannot read properties of undefined (reading 'length')

解決方法

ネストされたものは、正しい構文で指定します。また事前に判定することでエラーは回避できます。

const obj = {a: {b:[10,11],c:[20,22]}, d: [30,31]};

// undefinedであるかを判定してから使用
if(typeof obj.a.b !== "undefined"){

  console.log(obj.a.b); // [10, 11]

  console.log(obj.a.b.length); //2

}

// undefinedであるかを判定すればエラーは回避されます
if(typeof obj.f !== "undefined"){

  console.log(obj.f);

  console.log(obj.f.length);

}

また、存在しない場合は「空文字」の長さを取得するように「Null 合体演算子」を使用して、対処することもできます。

const obj = {a: {b:[10,11],c:[20,22]}, d: [30,31]};

console.log( (obj.b ?? '').length ); // 0

console.log( (obj.f ?? '').length ); // 0

console.log( (obj.a.b ?? '').length ); // 2

console.log( (obj.d ?? '').length ); // 2

変数の初期化忘れ

以下のコードのように、変数が配列として初期化されていない場合にも発生します。

let newarr;

let arr = [1, 2, 3, 4, 5];

for (const item of arr) {

  let num = item + 1;
  
  newarr.push(num); // Uncaught TypeError: Cannot read properties of undefined (reading 'push')

}

console.log(newarr);

解決方法

変数「newarr」を配列として初期化しておきます。

let newarr =[];

let arr = [1, 2, 3, 4, 5];

for (const item of arr) {

  let num = item + 1;
  
  newarr.push(num);

}

console.log(newarr); // [2, 3, 4, 5, 6]