함정 시리즈

[JavaScript] new Array(3).fill([]) - 참조 자료형의 함정

노새두마리 2023. 9. 23. 15:51

문제

// 길이가 3인 배열을 만들어 빈 배열을 채웁니다.
const arr = new Array(3).fill([]);

// arr의 첫 번째 배열에 요소를 추가합니다.
arr[0].push(1);

arr; // [[1], [1], [1]] ?

오직 0번 인덱스의 배열에만 접근하여 값을 추가했음에도 불구하고 모든 배열에 값이 추가되었습니다.

이는 곧 fill 메서드의 적용 결과로써 각각의 인덱스에 대하여 새로운 배열이 할당된 것이 아니라 메서드의 인자로써 전달된 배열 하나만으로 모든 자리를 채웠다는 이야기가 됩니다.

모든 인덱스가 동일한 배열에 대한 참조를 가지고 있었기 때문에 발생한 문제입니다.


해결

fill 메서드를 호출한 뒤 map 메서드를 통해 배열을 할당합니다.

map 메서드를 사용하면 map 메서드가 순회할 때마다 새로운 배열을 생성하여 값을 할당하므로 위의 문제를 피할 수 있습니다.

map을 호출했는데도 값이 채워지지 않아요.

// before
const arr = new Array(3).fill([]);

// after
const arr = new Array(3).fill().map(v => []);
// ...
arr[0].push(1);

arr; // [[1], [], []]