[TIL] Array.fill()에 빈 객체([])를 전달했더니 생긴 일

일단해봐·2023년 8월 30일
0

TIL

목록 보기
1/1
post-thumbnail

📝 개요

DFS를 공부하던 중 2차원 배열을 만들기 위해 먼저 빈 객체를 가진 N개의 배열을 만들었다.

let N = 5
let arr = new Array(N).fill([])

console.log(arr) // [[],[],[],[],[]]

그리고 이 배열을 0의 값으로 찬 총 NxN개의 2차원 배열로 만들어주기 위해서
아래와 같이 for문과 push 메서드로 배열을 체워넣으려고 했다.

let N = 5
let arr = new Array(N).fill([])

for(let i = 0; i<N; i++) {
  for(let j =0; j<N; j++){
    arr[i].push(0)
  }
}

console.log(arr) 

하지만 예상한 결과와 다르게 N^2 x N개의 배열이 결과로 나왔다. ( 2차원 배열을 만드는 다른 좋은 방법들도 있지만 Array를 써보고 싶었다.. )

❓ 원인

왜 이런 결과가 나왔을까? 고민을 해보았는데 아마 빈 배열을 채워 넣는 과정에서 메서드 안의 빈 배열을 얕은 복사 했기 때문이라고 생각했다.

메서드 자체가 하나의 데이터를 모든 배열에 채워넣는 방식이니 얕은 복사를 통해 값을 할당했을 것 같다.

🔎 분석

그래서 fill로 채워 넣은 값들이 얕은 복사를 통해 같은 메모리를 가리키고 있다는 것을 증명하기 위해 자바스크립트로 변수가 가리키는 메모리 주소를 찾아보려고 한다.

여기까지 정리하고 구글에 열심히 찾아본 결과 자바스크립트로는 메모리 주소를 찾을 수 없다고 한다.

자바스크립트 엔진은 자바스크립트 언어의 컴파일러 역할을 하고 자바스크립트 엔진은 C++로 만들어져 어떻게든 찾자면 찾을 수는 있다고 하나 복잡하니 넘어가려고 한다..

😭 결론

결론은 조금 어렵게 생각했던 탓이지 결국 얕은 복사를 하냐 깊은 복사를 하냐의 차이였고 fill 메서드는 객체 타입을 얕은 복사하여 이러한 문제가 생긴 것 같다. 그러니 fill 메서드로 2차원 배열을 만들려고 하지 말자.

조금 찜찜하니 다음에 더 알아보자..

profile
안녕하세요, 프론트엔드 개발자가 될 열정적인 사람입니다.

0개의 댓글