const
로 배열과 객체를 선언할 때, 배열과 객체는 참조자료형이기 때문에 변수에 배열이나 객체 자체가 아닌 reference(주소)가 할당되기 때문이다.
먼저 상수를 선언하는 키워드 const
의 정의를 알아보자.
const
const 선언은 블록 범위의 상수를 선언한다.
상수의 값은 재할당할 수 없으며 다시 선언할 수도 없다. - MDN
const
로 선언한 상수는 재할당 및 재선언할 수 없다. 따라서 const
로 선언한 배열 또한 재할당 및 재선언될 수 없다.
const
로 선언된 배열에 값을 재할당하려고 하면 다음과 같이 에러가 나는 것을 확인할 수 있다.TypeError
가 뜨며, "상수에 할당을 했습니다."고 나온다.const cars = ['BMW', 'Benz', 'Volvo'];
cars = ['Audi', 'Tesla', 'Kia']; // 재할당
// ❗️Uncaught TypeError: Assignment to constant variable.
const cars = ['BMW', 'Benz', 'Volvo'];
const cars = ['Audi', 'Tesla', 'Kia']; // 재선언
// ❗️Uncaught SyntaxError: Identifier 'cars' has already been declared
const
라는 키워드가 오인되는 게 있는데,
이 키워드는 상수 배열(변하지 않는 배열)을 선언하는 것이 아니라.
배열의 상수 reference(변하지 않는 주소)를 선언하는 것이다.
배열은 참조 자료형이기 때문에 변수에 배열을 할당하면, 변수에는 배열 그 자체가 저장되는 것이 아니라 배열의 주소가 저장된다.
따라서, const
로 배열을 선언했을 때, 값에는 배열의 주소가 할당되어 있고, 이 주소는 변하지 않으며, 우리는 여전히 배열의 요소를 추가하거나 삭제할 수 있는 것이다.
const fruit = { name: 'Apple', price 120 };
위의 그림에서 변수 fruit
에 객체가 할당되어 있는데, 변수의 값을 저장하는 Stack에는 객체의 주소인 #0001이 저장되어있고, Heap이라는 공간에 객체 자체가 저장되어 있다.
우리가 배열에 요소를 추가하거나, 객체의 속성을 변경하면 Heap에 저장된 데이터가 변경되는 것이지, const
로 선언된 배열과 객체의 주소는 변경되지 않기 때문에 const
로 배열이나 객체를 선언해도, 배열과 객체를 수정할 수 있는 것이다.
이 글은 아래 링크를 참고하여 작성한 글입니다.
https://www.w3schools.com/js/js_array_const.asp
https://akkisdiary.medium.com/pass-by-value-and-pass-by-reference-in-javascript-f621b43bc2e9