TIL 41 JavaScript - const arr = []은 상수인데 왜 값이 바뀔까?

Leo·2021년 7월 26일
0

Javascript

목록 보기
17/17
post-thumbnail

면접을 다니면서 받은 질문 중에 가장 인상깊었던 질문이 있다. 어떻게 보면 쉬운 질문이지만 생각해보면 그러네? 불가능한 것 아닌가? 왜 되는거지? 라고 생각할 수 있는 심오한 질문이었다.

const상수라고 했고, 값이 변할 수 없는데 const arr = []; arr.push('1');하면 값이 변한 것 아니냐? 이건 왜 되는 것이냐?

단순한 질문처럼 보이지만 생각해보니 분명 const 키워드는 immutable하고 위키백과에 상수를 검색해도 분명 상수란 변하지 않고, 항상 일정한 값을 갖는 수라고 정의되어 있다.

하지만 여기서 우리가 착각하면 안되는 것이 있다. 위의 질문에서 arr은 배열이었다. 배열은 객체 타입이며 변경 가능한 값(mutable value)이다. 그래서 배열의 값 자체는 변경이 될 수 있지만, 상수로 선언됐기 때문에 재할당은 되지 않는 것이다. 재할당을 하게 되면 가리키고 있는 주소가 변경되기 때문에 이는 불가능하다.

const arr = [1,2,3];
console.log(arr) // [1, 2, 3]

arr.push(4);
console.log(arr); // [1, 2, 3, 4]

arr = [0]; // error : "arr" is read-only

위 예시를 보면 const arrarr.push(4)를 하면 상수지만 값이 바뀌었다고 생각할 수 있다. 물론 배열 안의 값 자체는 바뀌었지만 arr의 관점에서 가리키고 있는 주소 자체는 바뀌지 않았다.

결국, 상수인데 값이 바뀐 것 처럼 보이지만(실제로 바뀌었지만), 가리키고 있는 주소 자체가 바뀐 것은 아니기 때문에 arr의 입장에서는 값이 바뀌지 않는다고 생각한다.

그림으로 좀 더 쉽게 이해해보자.

배열의 값이 변경되니 const키워드로 선언된 배열은 push()pop() 메소드가 실행되면 안된다고 생각할 수 있다. 하지만 가리키고 있는 주소 자체는 변경되지 않아서 가능한 것이다.

하지만 const arr재할당을 하게 되면 이는 참조하는 주소가 바뀌기 때문에 이제서야 값이 바뀐다고 생각하여 이는 불가능하다고 에러가 발생하는 것이다.

정리

  • const로 선언한 배열은 바뀔 수 있다.
  • 배열 자체의 값이 바뀌는 것은 가리키는 주소가 바뀐 것이 아니기 때문이다.
  • const로 선언한 배열의 재할당은 불가능 하다.
  • 재할당을 한다는 것은 가리키는(참조하는) 주소가 바뀌고, 상수는 처음 가리키고 있는 주소가 바뀔 수 없다.
profile
느리지만 확실하게

0개의 댓글