[TIL/모던 자바스크립트 Deep Dive] 2023/05/17
값에 의한 전달이전에, 원시 값은 '변경 불가능한 값'이기 때문에, 변수에 새로운 원시 값을 재할당하면 변수가 가리키던 메모리 공간의 주소가 변경된다고 정리한 바 있다. 원시 값이 변경 가능한 값이라면 메모리 주소를 바꿀 필요없이 원시 값 자체를 변경하면 그만이기 때문
11장. 원시 값과 객체의 비교
11-1. 원시 값
값에 의한 전달

이전에, 원시 값은 '변경 불가능한 값'이기 때문에, 변수에 새로운 원시 값을 재할당하면 변수가 가리키던 메모리 공간의 주소가 변경된다고 정리한 바 있다. 원시 값이 변경 가능한 값이라면 메모리 주소를 바꿀 필요없이 원시 값 자체를 변경하면 그만이기 때문이다.
위 예제는 정확히 동일한 논리를 취한다. 핵심은 "변수에 변수를 할당했을 때 무엇이 어떻게 전달되는가?" 하는 점이다.
가장 먼저, score는 변수 값 80으로 평가되기에, copy 변수에도 80이 할당될 것이다. 단, 새로운 숫자 값 80이 생성되어 copy 변수에 할당되는 것이다.
변수에 변수를(=원시 값을 갖는 변수를) 할당하면 할당받는 변수(copy)에는 할당되는 변수(score)의 원시 값이 복사되어 전달된다. 이것이 곧 ``값에 의한 전달``이다.

숫자 값 80을 갖는다는 점에서는 두 변수(score, copy)가 동일하다. 그러나 score 변수와 copy 변수의 값 80은 다른 메모리 공간에 저장된 ``별개의 값``이다. 증거는 다음과 같다.

copy 변수에 score 변수를 할당하는 과정에서, 각 변수는 서로 다른 메모리 주소를 갖게 된다. 따라서 score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향도 주지 않게 된다.

앞에서 언급한 내부 동작은 실제와 다를 수 있다. 이게 무슨 말이냐?
ECMAScript 사양에는 변수를 통해 메모리를 어떻게 관리해야 하는지 명확하게 정의되어 있지 않다. 가령 파이썬은 변수에 원시 값을 갖는 변수를 할당하는 시점에는 두 변수가 같은 원시 값을 참조하다가, 어느 한쪽의 변수에 재할당이 이뤄졌을 때 비로소 새로운 메모리 공간에 재할당된 값을 저장한다. 변수에 변수를 할당하는 시점에 두 변수가 서로 다른 메모리 주소를 갖게 된다는 기존의 논리와 다르다는 얘기이다.
추가적으로, ``값에 의한 전달``이라는 용어 자체가 ECMAScript 사양에서 등장하지 않는다. '값에 의한 전달'이라는 용어가 자바스크립트를 위한 용어가 아니기에 오해의 여지가 있다. 엄밀히 따지면 변수에는 '값'이 전달되는 것이 아니라 '메모리 주소'가 전달되기 때문이다. 변수로 대표되는 '식별자'는 '값'이 아니라 '메모리 주소'를 기억한다.

위 예제로 표현해보면 다음과 같다. 식별자 x는 '메모리 공간에 저장된 값인 10'을 식별할 수 있다. ``변수에 전달된 메모리 주소를 통해서!``
한마디로, '값에 의한 전달'도 사실은 값을 전달하는 것이 아니라 메모리 주소를 전달한다. 다만, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.
결론=> 내부 동작이 어떻든, 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없게 된다.
11-2. 객체
객체는 프로퍼티의 개수가 정해져 있지 않다. 동적으로 추가되고 삭제되며, 프로퍼티 값에도 별다른 제약이 없다. 객체는 원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없는 복합적인 자료구조이다.
기본적으로 원시 값과 다른 방식으로 동작하도록 설계되어 있기에, 원시 값과의 비교를 통해 객체를 이해해 봤다.
변경 가능한 값
객체는 ``변경 가능한 값(mutable value)``이다.

변수에 다음과 같은 객체를 할당한 상황이라고 가정하자.
만약 변수에 '원시 값'을 할당했다면, 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 '원시 값'에 접근할 수 있다. 객체의 경우에는 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 ``참조 값(reference value)``에 접근할 수 있다.
객체 '{name: "Lee"}'가 '0x00001332'라는 주소에 저장되어 있다면, 변수 person에 저장되어 있는 것은 '0x00001332'라는 주소이다. 해당 주소를 '참조 값'이라고 부른다.

따라서 용어를 재정립할 필요가 있다. 원시 값을 할당한 변수는 일반적으로 "변수는 ~~한 값을 갖는다."라고 표현했다. 객체를 할당한 변수는 "변수는 ~~한 객체를 참조하고 있다."라고 표현하는 것이 논리적으로 타당하다. "변수는 ~~한 객체를 가리킨다(point)."라고도 표현할 수 있겠다.


핵심은 객체를 할당한 변수에 재할당을 한 것은 아니기에, 객체를 할당한 변수의 참조 값은 변경되지 않는다는 점이다.
객체를 변경할 때마다 원시 값처럼 이전 값을 복사해서 새롭게 생성한다면 좋겠지만(=명확하고 신뢰성이 확보되겠지만), 객체는 크기가 매우 클 수도 있고, 원시 값처럼 크기가 일정하지도 않으며, 프로퍼티 값이 객체일 수도 있어서 복사해서 생성하는 비용이 많이 든다. 메모리를 보다 효율적으로 사용하기 위해 객체가 mutable value로 설계된 것이다.
치명적인 부작용이 하나 있는데, 원시 값과는 다르게 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 점이다.
참조에 의한 전달

객체를 가리키는 변수(person)를 다른 변수(copy)에 할당하면 원본의 ``참조 값`이 복사되어 전달되는데 이를 `참조에 의한 전달``이라 한다. 위에서 언급한, '여러 개의 식별자가 하나의 객체를 공유'하는 상황이다.
오해하면 안되는 것은, 원본 person과 사본 copy는 저장된 메모리 주소는 다르다. 참조 값이 동일한 것이다. 원본 또는 사본 중 어느 한쪽에서 객체의 프로퍼티 값을 변경하거나 프로퍼티를 추가 또는 삭제하면 두 변수가 서로 영향을 주고받게 된다. 앞서 언급한 '부작용'이 바로 이것이다.

자바스크립트에서 '참조에 의한 전달'은 존재하지 않는다. 굳이 따지자면 '값에 의한 전달'만이 존재한다. 식별자가 기억하는 메모리 공간에 '원시 값'이 있는지 '참조 값'이 있는 지의 차이만 있을 뿐, 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서는 동일하기 때문이다.
다만 교재에서는 전달되는 값의 종류가 원시 값인지 참조 값인지 구별해서 강조하는 의미에서 '값에 의한 전달'과 '참조에 의한 전달'이라는 용어를 사용한 것이다.
마지막은 핵심을 잘 이해했는지를 판단할 수 있는 예제 코드이다.

다음 글은 '함수' 파트를 다루기 전에, 얕은 복사와 깊은 복사에 대한 개념을 먼저 다루도록 하자!
More to read
Amazon VPC Architecture 이해하기
새로운 프로젝트를 기획하며, 개발에서 무엇을 가장 먼저 고민해야 하는지 다시 돌아보게 되었습니다.한때는 프론트엔드가 모든 설계의 출발점이라고 믿었습니다. 유저가 무엇을 보고, 어떤 흐름에서 머무르고 이탈하는지에 대한 이해 없이 서비스를 만든다는 건 불가능하다고 생각했기
'원사이트'프론트엔드 관점으로 알고리즘 이해하기
오랜만에 방법론에 관한 글을 쓰게 되었습니다. 최근 상황은 이렇습니다. SSAFY에서는 하루에 엄청난 양의 알고리즘 문제들을 과제로 수행하게 됩니다. 그 과정에서, '구현력'이 매우 떨어진다는 생각이 들었습니다. 완전히 어려운 문제라면 '아쉬움'이라는 감정조차 느끼지
SubnetVPC 설계의 시작: IP와 Subnet
반복되는 루틴 속에서 얻은 안정감을 발판 삼아, 이제는 기술적 스펙트럼을 넓히기 위한 개인 프로젝트에 착수하고자 합니다.이번 프로젝트의 목표는 단순한 포트폴리오 구축을 넘어, 실제 서비스 수준의 블로그 시스템 구현과 다국어 처리 적용 등 실무에 가까운 역량을 한 단계