javascript エラー「Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’)」の解決方法
- 作成日 2022.05.10
- 更新日 2022.12.06
- javascript
- javascript
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]
-
前の記事
Linux コマンドでユーザーidを確認する 2022.05.09
-
次の記事
java splitで複数の区切り文字を使用する 2022.05.10
コメントを書く