본 포스팅은 '모던 자바스크립트 Deep Dive'를 기반으로 공부한 내용을 정리한 것입니다.
원시 타입과 객체 타입은 근본적으로 다르다!
값에 의한 전달
) 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.(참조에 의한 전달
)원시 값은 변경 불가능한 값이다. 이말은 원시 값 자체를 변경할 수 없다는 것이며, 변수 값은 언제든지 재할당을 통해 변경 가능하다.
var score; // 1. 변수 선언
score = 80; // 2. 값의 할당
score = 90; // 3. 값의 재할당
위의 예제에서 세 단계 모두 변수가 참조하는 메모리 공간의 주소가 다르다. 그 이유는 변수에 할당된 원시 값이 변경 불가능하기 때문이다.
원시 값이 변경 가능한 값이라면, 세 단계에서 모두 참조하는 메모리 공간의 주소가 같아야한다.
문자열은 원시 타입의 크기가 정해져있는 다른 원시 값과 달리, 몇 개의 문자로 이루어졌느냐에 따라 필요한 메모리 공간의 크기가 결정된다. 1개의 문자는 2바이트의 메모리 공간에 저장되어, 이에 비례하여 결정된다.
배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체이다. 문자열 또한 이러한 특성을 가진다.
var str = 'string';
console.log(str[0]); // s
하지만 언제든지 동적으로 변경간으한 객체와는 달리 원본값을 변경할 수는 없다.
var str = 'string';
str[0] = 'S'
console.log(str); // string
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에 원시 값이 복사되어 전달된다. (할당받는 변수, 즉 복사하고자 하는 메모리 공간에 복사되는 값 자체가 전달되는 것이다.)
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
의 뜻은 '값을 복사하여 전달한다'는 뜻 뿐이다. 같다는 뜻이 아니다. (변수가 각각 다른 메모리 주소를 참조하는 특성에 의해)
객체는 변경 가능한 값이다.
변수에 객체를 할당하면, 변수가 원시 값 자체를 값으로 가지는 것과 달리, 객체를 할당한 변수는 객체가 저장된 메모리에 접근할 수 있는 메모리 공간의 주소, 즉 참조값
을 가지게 된다.
이러한 원리에 의해 "변수는 객체를 참조하고 있다" 또는 "변수는 객체를 가리키고 있다"라고 표현한다.
객체는 원시값과 달리 복잡한 자료구조를 가지고 있기 때문에 메모리 사용의 효율성과 성능을 위해 변경 가능한 값으로 설계되어 있다.
원시 값과는 다르게 여러개의 식별자가 하나의 객체를 공유할 수 있다. (뒤에서 다뤄보도록 한다.)
객체를 가리키는 변수를 다른 변수에 할당할 때 원본의 참조 값이 복사되어 전달되는 것을 참조에 의한 전달
이라 한다. 이 때 하나의 객체를 여러 식별자가 공유할 수 있게 된다.
var person = {
name: 'Lee'
}
var copy = person;
위의 예제를 살펴보자.
앞서 살펴봤듯이 객체를 변수에 할당하면 변수가 가리키는 메모리 공간에 객체가 저장되는 것이 아니라, 객체가 저장된 다른 메모리의 주소를 가리키는 참조 값이 저장된다.
person
이라는 변수가 A
라는 메모리를 가리키며 그곳에 저장된 참조 값은 B
라고 해보자. 여기서 B
는 객체 값이 저장된 다른 메모리 공간의 주소 C
를 가리킨다. var copy = person;
에서 변수 person
에 저장된 참조 값 B
가 전달된다. 그러면 변수 person
과 copy
모두 한 메모리 주소를 가리키는 참조 값 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'}
위에서 설명한 내용에 의해 person
과 copy
가 동시에 변경되었다.