문제 상황: fill()은 새 인스턴스가 아닌 참조를 전달합니다
JavaScript에서 Array.prototype.fill() 메서드를 객체와 함께 사용하면 주의해야 할 중요한 함정이 있습니다. 이 메서드는 각 요소에 새로운 객체 인스턴스를 만들어 넣는 것이 아니라, 동일한 객체에 대한 참조를 모든 슬롯에 복사합니다.
그 결과, 배열의 한 요소에서 값을 변경하면 나머지 모든 요소의 값까지 함께 변경되는 예상치 못한 동작이 발생할 수 있습니다.
해결 방법: map() 활용하기
이 문제를 해결하려면 fill() 뒤에 map() 메서드를 연결하여 사용하면 됩니다. 문법은 다음과 같습니다.
var anyVariableName = new Array(yourSize).fill().map(Object);
여기서 fill()을 인자 없이 호출하면 배열이 undefined 값으로 채워지고, 이후 map(Object)가 각 요소마다 새로운 빈 객체를 생성해 줍니다. 덕분에 배열의 모든 요소가 서로 독립된 개별 객체가 됩니다.
참고: .map(() => ({}))처럼 화살표 함수를 사용해도 동일한 효과를 얻을 수 있습니다.예제 코드
다음은 실제 동작을 확인할 수 있는 코드입니다.
var arrayOfObject = new Array(5).fill().map(Object); console.log(arrayOfObject);
위 프로그램을 실행하려면 터미널에서 다음 명령어를 입력합니다.
node fileName.js
여기서는 파일 이름이 demo311.js라고 가정하겠습니다.
실행 결과
위 코드를 실행하면 다음과 같은 출력이 나타납니다.
PS C:\Users\Amit\javascript-code> node demo311.js
[ {}, {}, {}, {}, {} ]출력 결과를 보면 5개의 빈 객체가 담긴 배열이 생성되었으며, 이 객체들은 각각 독립적인 인스턴스입니다. 따라서 특정 요소에 속성을 추가하거나 수정해도 다른 요소에는 영향을 주지 않습니다.