본인은 for문을 중첩해서 2차원 배열을 만드는 시도를 하였다.
const twoDimArray = function(a,b){
const arr = new Array(3).fill([]);
for(let i=0; i<a; i++){
for(let j=0; j<b; j++){
arr[i][j] = i;
}
}
return arr
}
console.log(twoDimArray(3,4))
// [[0,0,0,0],[1,1,1,1],[2,2,2,2]] 를 리턴할 것으로 기대했지만,
// [[2,2,2,2],[2,2,2,2],[2,2,2,2] 가 리턴되었다.
처참히 실패하였다. 왜일까?
이유는 arr를 초기화하는 과정에서 new Array(3).fill([])
를 사용한 것에 있었다.
영어에 익숙하다면 스택오버플로우에 질문한 본인의 질답을 참고해보자.
정리하자면, fill() 로 배열을 Array의 빈칸에 전달하는 과정에서 문제가 생긴 것이다.
pass by value 될 수 있는 primitive type (string, integer, boolean...) 과 달리 pass by reference 되는 reference value인 배열은 fill에 전달되면 배열 그 자체가 전달되는 것이 아닌 배열을 가리키는 주소가 전달되어 새롭게 생성된 Array의 3개의 빈칸을 채우게 된다.
따라서 이후 배열의 값을 변경하게 되면 모든 배열이 동일하게 하나의 배열을 참조하며
[[0,0,0,0],[0,0,0,0],[0,0,0,0]]
=> [[1,1,1,1],[1,1,1,1],[1,1,1,1]]
=> [[2,2,2,2],[2,2,2,2],[2,2,2,2]]
의 순서대로 변하게 되어 마지막 예상치 않은 값을 리턴하게 되는 것이다.
마지막으로 참고한 자료들을 링크한다.
자바스크립트 Primitive vs Reference values
자바스크립트 'pass by value' or 'pass by reference'