이 게시물은 SW마에스트로 연수생 간 진행한 Modern JavaScript DeepDive 스터디 개인 정리 내용입니다.
되도록 책의 내용을 그대로 적기보단 개인적으로 인상깊었던 부분을 구어체로 풀어쓰려 노력했습니다.
Modern JavaScript Deep Dive
Chapter _ 11 원시 값과 객체의 비교
자바스크립트에서 사용되는 7가지 데이터 타입을 가장 크게 구분한다면 원시타입 과 객체타입 으로 구분할 수 있습니다.
이 둘의 가장 큰 차이점은 불변성 입니다.
원시타입의 값은 Immutable. 즉 바뀔 수 없는 불변성 값입니다. 하지만 객체의 값은 Mutable 한 바뀔 수 있는 값이라는 점.
원시 값을 변수에 할당하면 변수에는 실제 값이 저장되고, 객체를 변수에 할당하면 참조값이 저장됩니다.
여기서 원시값을 변수에 할당 하는 것을 값에 의한 전달 Call by Value
객체를 가리키는 변수를 다른 변수에 할당하는 것을 참조에 의한 전달 Call by Reference 라고 부릅니다.
원시 값
처음 시작하며 원시 값은 변경 불가능한 불변성 값이라고 설명드리며 시작했습니다.
“원시 값은 변경 불가능하다” 라는 말은 원시값 자체의 불변성을 의미하는 것이고 변수는 언제든지 재할당을 통해 변경할 수 있습니다.
그러한 재할당마저 막힌 상수가 존재하지만 이 또한 원시값과 비교하는것은 옳지 못합니다.
어찌되었건 상수는 재할당이 불가능한 “변수” 를 의미하기 때문입니다.
값에 의한 전달 ( Call by Value )
1
2
3
4
5
6
7
8
9
var score = 80
var copy = score
console.log(score) // 80
console.log(copy) // 80
score = 100
console.log(score); // 100
console.log(copy) // => 무엇이 나올까요?
위의 짧은 예제를 한번 보겠습니다.변수에 원시값을 갖는 변수를 할당한다면 Call by Value. 값에 의한 전달이 진행됩니다.
이는 변수에 할당되는 원시값이 복사되어 전달된다는 뜻입니다.
따라서 매 값마다 메모리가 할당되어있는 원시값의 경우 같은 값(Value) 를 가지고 있더라도 별개의 공간에 저장된 별개의 값이라고 볼 수 있습니다.
이러한 로직이 오해를 불러올 순 있지만 조금 더 엄격하게 표현하자면 변수에 전달되는 것이 값이 아닌 불변값의 메모리 주소이기 때문이기도 합니다.
즉, 해당 주소를 방문하게 되면 값을 반환받을 수 있는 주소값을 담고 있다는 말로도 설명 할 수 있을 것 같습니다.
객체
객체는 모든 값들이 동적으로 정해질 수 있는 변경 가능한 값이다. 심지어 객체 안의 객체를 할당하는 것 마저 가능합니다!
즉, 객체의 경우 원시값과 비교해서 복잡하고 구현이 어려울 가능성이 훨씬 높습니다.
따라서 객체를 생성하고 접근하는 과정에 들어가는 비용도 원시값과 비교해서 클 가능성이 높다는 말이 됩니다.
그렇기 때문에 객체는 원시값과는 조금 다른 방식으로 동작하도록 설계 되어 있습니다.
직접 비교해보자면,
원시값은 변경 불가능한 값이므로 원시값을 갖는 변수의 값을 변경하기 위해선 재할당 외엔 방법이 없습니다.
하지만 객체는 변경가능한 값으로 객체를 할당한 변수는 재할당 없이 직접 동적으로 변경 할 수도, 값을 갱신할수도, 프로퍼티 자체를 삭제할 수도 있습니다.
하지만 이러한 방식에서 객체를 생성하고 관리하는 방식은 원시값에 비교하여 훨씬 복잡하여 큰 비용을 요구하는 방법입니다.
따라서 이것을 최적화하기 위해 참조에 의한 전달 Call by Referance 을 사용합니다.
참조에 의한 전달 Call by Referance
이를 단순하게 설명하자면 두 개 이상의 식별자가 하나의 객체를 공유한다는 것을 의미합니다.
즉, 어느 한 쪽에서라도 객체를 변경한다면 공유중인 모든 식별자에 영향을 준다는 것을 의미하기도 합니다.
정리
Call by Value 와 Call by Ref 가 의미하는 바는 식별자가 메모리 공간의 값을 복사하여 전달한다는 점은 동일하나, 그 값이 원시값인지 참조값인지에 대한 차이만이 존재합니다.
물론 여기서 나온 Call by Ref 도 일반적으로 사용되는 C++ 이나 JAVA 에서의 Call by Ref 와는 확연한 차이가 있으니 그 점은 유의하면 좋을 것 같다.
