Today I Learned 17 - JavaScript Deep Dive / 원시 값과 객체의 비교

angie·2022년 6월 28일
0

JavaScript Deep Dive

목록 보기
8/18
post-thumbnail

본 포스팅은 '모던 자바스크립트 Deep Dive'를 기반으로 공부한 내용을 정리한 것입니다.

원시 타입과 객체 타입의 차이점

원시 타입과 객체 타입은 근본적으로 다르다!

  • 값의 변경 가능성 : 원시 값은 변경 불가능한 값이고, 객체 타입의 값은 변경 가능한 값이다.
  • 저장되는 값의 차이 : 원시 값을 변수에 할당하면 실제 값이 저장된다. 객체는 변수에 할당하면 참조 값이 저장된다.
  • 복사할 때 전달되는 값의 차이 : 원시 값을 갖는 변수를 다른 변수에 할당하면 원시 값이 복사되어 전달된다.(값에 의한 전달) 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.(참조에 의한 전달)

1. 원시 값

1) 변경 불가능한 값

원시 값은 변경 불가능한 값이다. 이말은 원시 값 자체를 변경할 수 없다는 것이며, 변수 값은 언제든지 재할당을 통해 변경 가능하다.

var score;   // 1. 변수 선언
score = 80;  // 2. 값의 할당
score = 90;  // 3. 값의 재할당

위의 예제에서 세 단계 모두 변수가 참조하는 메모리 공간의 주소가 다르다. 그 이유는 변수에 할당된 원시 값이 변경 불가능하기 때문이다.
원시 값이 변경 가능한 값이라면, 세 단계에서 모두 참조하는 메모리 공간의 주소가 같아야한다.

2) 문자열과 불변성

문자열은 원시 타입의 크기가 정해져있는 다른 원시 값과 달리, 몇 개의 문자로 이루어졌느냐에 따라 필요한 메모리 공간의 크기가 결정된다. 1개의 문자는 2바이트의 메모리 공간에 저장되어, 이에 비례하여 결정된다.

유사 배열 객체인 문자열

유사 배열 객체란?

배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체이다. 문자열 또한 이러한 특성을 가진다.

var str = 'string';

console.log(str[0]);  // s

하지만 언제든지 동적으로 변경간으한 객체와는 달리 원본값을 변경할 수는 없다.

var str = 'string';
str[0] = 'S'
console.log(str);  // string

3) 값에 의한 전달

변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에 원시 값이 복사되어 전달된다. (할당받는 변수, 즉 복사하고자 하는 메모리 공간에 복사되는 값 자체가 전달되는 것이다.)

var score = 80;

var copy = score;
console.log(score, copy);  // 80 80

score = 100;
console.log(score, copy);  // 100 80

위의 예제를 보자.
먼저 score라는 변수를 선언하고 할당한 뒤, copy라는 변수에 score의 값을 복사했다. 때문에 score와 copy의 값이 80으로 동일하다.
하지만 score=100으로 값을 재할당하면, score와 copy는 각각 다른 메모리 공간을 참조하기 때문에 각 변수의 값을 변경해도 서로 어떠한 영향도 주지 않는다.

즉, var copy = score의 뜻은 '값을 복사하여 전달한다'는 뜻 뿐이다. 같다는 뜻이 아니다. (변수가 각각 다른 메모리 주소를 참조하는 특성에 의해)

2. 객체

1) 변경 가능한 값

객체는 변경 가능한 값이다.

객체가 변수에 할당되는 원리

변수에 객체를 할당하면, 변수가 원시 값 자체를 값으로 가지는 것과 달리, 객체를 할당한 변수는 객체가 저장된 메모리에 접근할 수 있는 메모리 공간의 주소, 즉 참조값을 가지게 된다.
이러한 원리에 의해 "변수는 객체를 참조하고 있다" 또는 "변수는 객체를 가리키고 있다"라고 표현한다.

객체가 변경 가능하게 설계된 이유

객체는 원시값과 달리 복잡한 자료구조를 가지고 있기 때문에 메모리 사용의 효율성과 성능을 위해 변경 가능한 값으로 설계되어 있다.

객체가 변경 가능하여 생기는 구조적 문제

원시 값과는 다르게 여러개의 식별자가 하나의 객체를 공유할 수 있다. (뒤에서 다뤄보도록 한다.)

2) 참조에 의한 전달

객체를 가리키는 변수를 다른 변수에 할당할 때 원본의 참조 값이 복사되어 전달되는 것을 참조에 의한 전달이라 한다. 이 때 하나의 객체를 여러 식별자가 공유할 수 있게 된다.

var person = {
  name: 'Lee'
}

var copy = person;

위의 예제를 살펴보자.
앞서 살펴봤듯이 객체를 변수에 할당하면 변수가 가리키는 메모리 공간에 객체가 저장되는 것이 아니라, 객체가 저장된 다른 메모리의 주소를 가리키는 참조 값이 저장된다.
person이라는 변수가 A라는 메모리를 가리키며 그곳에 저장된 참조 값은 B라고 해보자. 여기서 B는 객체 값이 저장된 다른 메모리 공간의 주소 C를 가리킨다. var copy = person;에서 변수 person에 저장된 참조 값 B가 전달된다. 그러면 변수 personcopy 모두 한 메모리 주소를 가리키는 참조 값 B를 가지게 된다.
이러한 결과로 원본(person) 또는 사본(copy) 중 어느 한 쪽에서 객체를 변경하면 서로 영향을 주고 받아 동시에 변경된다.

var person = {
  name: 'Lee'
}
var copy = person;

copy.name = 'Kim';
person.address = 'Seoul';

console.log(person);   // {name: 'Kim', address: 'Seoul'}
console.log(copy);     // {name: 'Kim', address: 'Seoul'}

위에서 설명한 내용에 의해 personcopy가 동시에 변경되었다.

profile
better than more

0개의 댓글