Array.fill()과 데이터 카피

이동규 (Justin)·2020년 6월 11일
0
post-thumbnail

본인은 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'

profile
Frontend Developer, JamStack, Ethereum

0개의 댓글