[Javascript] 원시 값과 객체, pass by value / pass by reference

jwo0o0·2022년 7월 11일
0

Javascript

목록 보기
3/4
post-thumbnail

원시 타입(primitive type)

자바스크립트에서는 모든 데이터를 원시 타입 또는 객체 타입으로 나누는데 그 중 원시 타입에는

  • number
  • string
  • boolean
  • undefined
  • null
  • symbol

위와 같은 타입들이 속한다.

💡 원시 타입의 특징

📌 immutable 하다.

원시 타입의 값은 불변성, 즉 immutable 하고 읽기 전용이라는 특징인데, 여기서 의문이 생길 수 있다.

var num = 123;
console.log(num); // 123 출력

num = 456;
console.log(num); // 456 출력

다음과 같은 코드에서 원시 타입, number 타입인 변수 num의 값이 바뀐거 아닌가? 🧐 라고 생각할 수도 있지만 여기서 바뀐건 123, 456 같은 '값' 자체가 아니라 number type '변수'가 가리키고 있는 값이다.

먼저 변수와 값이 차이를 알아보자.
✏️ 변수: 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 / 메모리 공간을 식별하기 위해 붙인 이름
✏️ : 변수에 저장된 데이터 / 표현식이 평가되어 생성된 결과

이 그림을 보면 더 잘 이해할 수 있는데, 우선 score라는 변수를 선언하면 자바스크립트 엔진이 undefined로 초기화 한다. 즉 score 변수가 undefined 라는 값이 저장된 변수를 가리킨다. 그리고 score에 값 80을 할당하면, 변수 score는 80 이라는 값이 저장된 메모리 공간을 가리킨다. 마찬가지로 변수 score에 90을 재할당하면 score는 이제 90 이라는 값이 저장된 메모리 공간을 가리킴으로써 재할당된다.

✓ 결론적으로 변경 불가능하다는 것은 '값'이다!
변수는 단지 재할당을 통해 저장하고 있는 값을 교체할 뿐이다.
이런 방식을 통해 자바스크립트는 데이터의 신뢰성을 보장할 수 있다.

📌 pass by value

앞서 원시 타입 변수는 단지 '값'을 저장할 뿐이고 '값' 자체는 immutable 하다는 것을 알아 보았다.
그리고 재할당을 통해 저장하는 값을 바꿀 수 있는데 그렇다면 다른 변수에 복사할 때는 어떨까?
원시 타입은 pass by value 라는 방식을 사용한다.

var score = 80;
var copy = score;


변수 copy에 score의 값을 복사해서 할당하는 과정이다.
pass by value, 값에 의한 전달 이라는 말처럼 copy에는 score가 저장하고 있던 '값' 80이 복사되어 저장된다.
✏️ 그림처럼 score와 copy는 각기 다른 메모리 공간을 가리키지만, 그 메모리 공간에는 모두 80이라는 값이 저장되어 있는 것이다.

💭 엄밀히 말하자면 pass by value도 사실은 메모리 주소를 전달하고 있다. 변수와 같은 식별자는 메모리 공간의 주소를 기억하고 그 주소로 값에 접근하기 때문이다.

객체 타입(object/reference type)

원시 타입을 제외한 나머지 모든 데이터 타입은 객체 타입에 속하는데, 여기에는

  • 객체
  • 함수
  • 배열

등이 있다.

💡 객체 타입의 특징

📌 mutable 하다.

원시 타입과 반대로 바뀔 수 있는 값, mutable 한 타입이 객체 타입이다.
그리고 가변적이라는 것은 프로퍼티, 즉 저장하는 값이 정해져 있지 않다는 말이다.
이렇게 되면 메모리 크기를 사전에 정해둘 수 없다. 그래서 객체 타입은 원시 타입과 다르게 '값'을 저장하지 않고 '메모리 주소'를 저장한다.

const person = {
  	name: 'Kia',
  	address: 'Seoul'
};


위 코드처럼 person이라는 객체를 선언했을 때, 객체 타입 person은 실제 값들이 저장되어 있는 메모리의 주소를 저장하고 있다. 그리고 값에 접근해야 할 필요가 생기면 저장하던 메모리 주소를 통해 참조 값(reference value)에 접근할 수 있다.

📌 pass by reference

따라서 값이 아니라 메모리 주소를 저장하고 전달하는 객체 타입의 이런 방식을 pass by reference라고 부른다.
단점은

  • 메모리의 효율적 소비가 어렵다. 아까도 말했듯이 크기가 가변적이기 때문이다. 따라서 잘 관리하지 못하면 성능이 나빠질 수도 있다.
  • 여러 개의 식별자가 하나의 객체를 공유할 수 있다. 메모리 주소만 있으면 값에 접근할 수 있기 때문이다. 그래서 이런 방식은 자칫하면 코드의 가독성을 떨어뜨리고 혼란을 야기할 수도 있다.

💡 pass by value vs. pass by reference

앞서 살펴본 두 방식의 공통점은
식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 것이다. 그리고 pass by value 방식 또한 pass by reference와 같이 '값이 저장된 메모리 주소'를 전달한다.

✏️ 따라서 엄밀히 따지면 javascript에서는 '참조에 의한 전달'은 존재하지 않는다. '값에 의한 전달'만 존재할 뿐. 그러나 원시 타입과 객체 타입이 값을 저장하고 다루는 방식에는 차이가 있기에 이런 식으로 구분해서 부르고 있다.

참고: 모던 자바스크립트 Deep Dive 11장

profile
개발로 밥벌이 하고 싶은 사람

0개의 댓글