JavaScript에서 신기한 걸 찾았습니다.

JS에서 변수 선언시에 var, let, const가 있는데.
const는 상수를 의미합니다. 그래서 한 번 선언되면 재할당이나 재선언이 안 됩니다.

그런데 신기하게도 상수라는 의미가 불변이라는 것을 보증하지는 않습니다.

const a = [1, 2, 3, 4, 5];

이런 배열을 만들었는데 여기에 a.push(6)를 하면,
a[1, 2, 3, 4, 5, 6]이 되버리죠.

또 이런 식으로 배열을 만들 수 있습니다.

const cats = [];
cats[0] = "냥이";
cats[1] = "댕댕이";
cats[30] = "캣홀릭"
console.log(cats); // ["냥이", "댕댕이", <empty slots>, "캣홀릭"]

마지막으로 제가 말씀드리고 싶은 신기한 것은 이런 조작도 가능하다는 것입니다.

const lastArray = ["a", "b", "c", "d", "e"]
console.log(lastArray.length) // 5

lastArray.length = 1
console.log(lastArray.length) // 1
console.log(lastArray) // ["a"]

이렇게 배열의 길이를 바꾸면, 뒤의 모든 배열 요소가 파괴적으로 사라집니다.
오늘 문서 읽다가 이거 보고 깜짝 놀랐습니다.
const로 선언했어도 배열이 절대로 불변일 것이다 믿으면 안 되겠습니다.

여담으로 혹시 다른 언어도 이렇게 변경되는가 궁금합니다.

저도 자세한건 잘 모르지만 객체같은 건 포인터처럼 잡고 쓴다고 생각하고 쓰고 있습니다 어디 자바 공부하다가 본거 같기도 하구
그래서 배열에 뭘 넣거나 객체 멤버변수 바꾸기 같은 걸 할 수 있다고 알고 있습니당

요건 저도 첨 보네요 싱기방기
아직 알아야 할게 많은거 같습니다

저는 const가 대입을 제외한 온갖 행위가 다 된다는 생각으로 쓰고 있습니다…

1 Like

@shjy9417 왜 사람들이 공식문서를 읽어보라는지 배웠습니다; 이런 기능(?)이 있다는 걸 처음 알았습니다.
@aig0016 단순히 값 선언이 아닌 이상, 온갖 것이 다 가능하겠다 생각해야겠습니다; 어디 회사에서 자격요건으로 JavaScript의 const가 왜 나쁜 설계인가 설명할 수 있다 가 있었는데, 이런 이유때문인가 싶기도 합니다.

이것저것 공부하다가 하나 알게 된 게 있어서 적습니다

Object.freeze를 쓰면 1레벨까지는 값을 불변하는 상태로 바꿀 수 있습니다.

> const a = [1,2,3,4,5]
undefined
> a
[ 1, 2, 3, 4, 5 ]

위와 같이 freeze를 쓰지 않는다면,

> a.pop()
5
> a
[ 1, 2, 3, 4 ]

이렇게 내부 요소가 변경되지만,

> Object.freeze(a)
[ 1, 2, 3, 4 ]

이렇게 freeze를 쓰면?

> a
[ 1, 2, 3, 4 ]
> a.pop()
Uncaught TypeError: Cannot delete property '3' of [object Array]
    at Array.pop (<anonymous>)
> a
[ 1, 2, 3, 4 ]

짠! pop을 해도 오류를 뿜어내고 내부 요소가 변경되지 않습니다!

> a[1] = 5
5
> a
[ 1, 2, 3, 4 ]
> a[1]
2

그리고 값 대입을 해도 요소가 변경되지 않습니다!

오래된 글타래긴 한데, freeze 보고 생각이 나서 적었습니다

2 Likes

오… 재밌는 걸 하나 알아갑니다.