본문 바로가기

개발/JavaScript

TypeError: Cannot read properties of undefined (reading '0')

배열의 인덱스를 접근할때 발생한 에러다.

에러 코드

function solution(arr){  
    let answer=0;
    let n=arr.length;
    let dx=[-1, 0, 1, 0];
    let dy=[0, 1, 0, -1];
    for(let i=0; i<n; i++){
        for(let j=0; j<n; j++){
            let flag=1;
            for(let k=0; k<4; k++){
                let nx=i+dx[k];
                let ny=j+dy[k];
               if(arr[nx][ny]>=arr[i][j]){
                    flag=0;
                    break;
                }
            }
            if(flag) answer++;
        }
    }  

    return answer;
}

1. 에러 발생

에러 내용은 다음과 같다.

if(arr\[nx\]\[ny\]>=arr\[i\]\[j\]){  
**TypeError: Cannot read properties of undefined (reading '0')**

1-1.에러가 발생한 원인

1) 나의 생각

undefined의 경우는 falsy한 값이므로 if문에서 false로 처리되어 해당 if문을 벗어날 것 이라 생각했다.
하지만 undefined인 배열의 인덱스 값에 접근할 경우는 에러가 발생하게 된다.

2) 예시를 들어보자
다음과 같은 배열이 있다고 가정해보자

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

console.log(arr[5]); // undefined
console.log(arr[-1][0]); // TypeError: Cannot read property '0' of undefined`

이 배열에서 인덱스가 0부터 4까지 존재한다.
따라서 arr[5] 와 같이 인덱스 범위를 벗어나는 값을 참조하면 자바스크립트는 "undefined" 값을 반환한다.

1) undefined

console.log(arr[5]); // undefined

에러는 아니지만, 프로그램의 동작을 예측하지 못하게 만들 수 있으므로 주의가 필요하다.
반면에 행 인덱스가 범위를 벗어나면, 해당 인덱스가 존재하지 않기 때문에 에러가 발생한다.

2) TypeEroor: Cannot read property '0' of undefined

console.log(arr[-1][0]); // TypeError: Cannot read property '0' of undefined`

이 오류는 배열 인덱스 -1이 유효하지 않기 때문에 arr[-1]이 undefined를 반환하고,
이후에 undefined[0] 을 참조하면서 발생한다.

즉, undefined 객체에 대해서는 인덱스 접근이 불가능하므로, 해당 코드에서는 오류가 발생한다.

1차원 배열의 인덱스는 일렬로 연속된 메모리 공간에 저장되어 있지만,
2차원 배열의 경우 각 행마다 별도의 메모리 공간을 사용하기 때문이다.
따라서 존재하지 않는 행에 대해 액세스하려고 하면 해당 메모리 공간이 없기 때문에 에러가 발생한다.

2. 해결방안

배열의 인덱스를 접근하기 전에 해당 인덱스가 유효한지 검사하는 로직을 추가했다.
추가한 로직은 다음과 같다.

if(nx>=0 && nx<n && ny>=0 && ny<n && arr[nx][ny]>=arr[i][j])

위의 조건을 추가한 완성 코드

           function solution(arr){  
                let answer=0;
                let n=arr.length;
                let dx=[-1, 0, 1, 0];
                let dy=[0, 1, 0, -1];
                for(let i=0; i<n; i++){
                    for(let j=0; j<n; j++){
                        let flag=1;
                        for(let k=0; k<4; k++){
                            let nx=i+dx[k];
                            let ny=j+dy[k];
                            if(nx>=0 && nx<n && ny>=0 && ny<n && arr[nx][ny]>=arr[i][j]){
                                flag=0;
                                break;
                            }
                        }
                        if(flag) answer++;
                    }
                }  

                return answer;
            }

            let arr=[[5, 3, 7, 2, 3], 
                     [3, 7, 1, 6, 1],
                     [7, 2, 5, 3, 4],
                     [4, 3, 6, 4, 1],
                     [8, 7, 3, 5, 2]];
            console.log(solution(arr));

3. 알게된 점

배열을 다룰 때는 항상 인덱스에 접근하기 전 범위 검사를 꼭 해주자!

[참고]

https://codingbeautydev.com/blog/javascript-cannot-read-property-0-of-undefined/

https://tiaz.dev/JavaScript/2

'개발 > JavaScript' 카테고리의 다른 글

ES5 to ES6  (0) 2023.04.09