레퍼런스 타입의 주의사항 - 배열

chance·2020년 2월 24일
0

javascript

목록 보기
2/6

해당 코드는 freecodecamp의 예제를 수정하여 만들었습니다.
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/debugging/use-caution-when-reinitializing-variables-inside-a-loop

function zeroArray(m, n) {
  // Creates a 2-D array with m rows and n columns of zeroes
  let newArray = [];
  let row = [];
  for (let i = 0; i < m; i++) {
    // Adds the m-th row into newArray

    for (let j = 0; j < n; j++) {
      // Pushes n zeroes into the current row to create the columns
      row.push(0);
    }
    // Pushes the current row, which now has n zeroes in it, to the array
    newArray.push(row);
  }
  return newArray;
}

let matrix = zeroArray(3, 2);
console.log(matrix);

결과

[ [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ] ]

해당 예제는 잘못된 변수 선언 위치로 인해 원하는 결과가 나오지 않는 코드입니다. 실행결과와 별개로 배열의 동작 방식을 복습할 수 있는 예제라서 가져왔습니다.

배열은 오브젝트의 일종이기에 레퍼런스 방식으로 동작합니다. 배열 객체가 수정된다면 해당 배열을 가리키고 있던 모든 변수들에도 변경 사항이 적용됩니다.
newArray 배열의 각각의 줄은 row 배열이 참조하고 있는 배열 객체와 같습니다. 따라서 row 배열에 push()로 값을 넣어준다면 newArray 배열의 모든 줄에도 값이 추가됩니다.

row.push(1);

결과

[ [ 0, 0, 0, 0, 0, 0, 1 ],
  [ 0, 0, 0, 0, 0, 0, 1 ],
  [ 0, 0, 0, 0, 0, 0, 1 ] ]

그러나, row에 새로운 배열을 할당하게 된다면 새로운 배열 객체를 row가 가르키게(참조하게) 됩니다. 따라서 기존 배열 객체에는 변경사항이 없기에 기존의 배열을 참조하고 있던 변수는 기존의 값을 출력하게 됩니다.

row = [1, 1, 1, 1, 1];
console.log(row);
console.log(newArray);

결과

[ 1, 1, 1, 1, 1 ]
[ [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ] ]
profile
프론트엔드와 알고리즘을 주로 다룹니다.

0개의 댓글