원시 타입 | 객체 타입 |
---|---|
변경 불가능한 값(immutable value) | 변경 가능한 값(mutable value) |
변수 할당 시 변수에 실제 값이 저장됨 | 변수 할당 시 참조 값이 저장됨 |
원시 값을 갖는 변수를 다른 변수에 할당 시 원시 값이 전달됨 | 객체를 가리키는 변수를 다른 변수에 할당 시 참조 값이 전달됨 |
값에 의한 전달 | 참조에 의한 전달 |
값을 변경할 수 없다 !== 재할당을 할 수 없다
원시 값을 할당한 변수에 새로운 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장한 후 새롭게 재할당한 원시 값에 포인터(메모리주소)를 넘긴다
이렇게 되면 변수가 참조하던 포인터(메모리주소)가 바뀌는 것
변수가 참조한 메모리 공간의 주소를 변경한 이유는 변수에 할당된 원시 값이 변경 불가능한 값이기 때문
원시 값의 이런 특성을 불변성이라고 함
var point = 1;
var copy = point;
copy = 2;
console.log(point); // 1
변수에 변수를 할당하는 경우, 할당 되는 변수(point)가 원시 값을 갖는 변수라면 할당 받는 변수(copy)에게는 할당되는 변수(point)의 원시 값이 복사되어 전달됨
이를 값에 의한 전달이라고 함
복사되어 전달되기 때문에 할당 받는 변수(copy)가 갖는 메모리 공간은 할당되는 변수(point)와 다른 메모리 공간을 사용하기 때문에 할당 받은 값을 변경해도 할당되는 변수는 아무런 영향을 받지 않음!
파이썬은 위 그림처럼 각각의 식별자의 포인터가 같은 곳을 가리키고 있다가 재할당이 일어날 때 이동하는데
JS 엔진에 따라 JS도 위처럼 동작할수도 있다.
객체는 할당이 이루어지는 시점에 객체 리터럴이 해석되고 객체가 생성됨
객체는 프로퍼티의 개수가 동적으로 추가되고 삭제할 수 있음
값에도 제약이 없음
원시값처럼 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없음
var group = {
people1: 'son',
people2: 'kim'
원시 값을 할당한 변수는 원시 값 자체를 값으로 가짐
객체를 할당한 변수는 참조 값을 값으로 가짐
참조 값 : 생성된 객체가 저장된 메모리 공간의 주소
객체리터럴은 언뜻 블록문 같지만 엄연한 표현식이기 때문에 세미콜론(;)을 붙여야 함
객체를 할당한 변수가 확보한 메모리 공간에는 생성된 객체가 실제로 저장된 메모리 공간의 주소가 저장되어 있음
이를 참조 값이라고 함 (변수는 이 참조 값을 통해 객체에 접근할 수 있음)
// 할당이 이루어지는 시점에 객체 리터럴이 해석되고 그 결과 객체가 생성됨
var group = {
people1: 'son'
};
// group 변수에 저장되어 있는 참조값으로 실제 객체에 접근하여 해당 객체를 반환
console.log(group.people1); // son
원시 값을 갖는 변수의 값을 변경하려면 재할당 외에는 방법이 없다.
하지만 객체는 생성된 후에도 프로퍼티를 동적으로 추가할 수 있고 프로퍼티(키)값을 갱신할 수 도 있으며 삭제도 가능하다
객체는 변경할 수 있는 값
var group = {
people1: 'son',
};
// 프로퍼티(키) 값 갱신
group.people1 = 'kim';
// 프로퍼티 동적 추가
group.people2 = 'park';
console.log(group); // {people1: "kim", people2: "park"}
이처럼 객체는 크기가 매우 클수도 있고 프로퍼티 값이 객체일 수도 있어서 원시 값처럼 복사(Deep copy)하는 것에 생성하는 비용이 많이 듬
때문에 메모리를 효율적으로 사용하기 위해 객체는 변경 가능한 값으로 설계되어 있음
하지만 이런 구조때문에 원시값과는 달리 여러 개의 식별자가 하나의 객체를 공유한다는 것이다.
var group = {
people1: 'son',
};
// 참조 값을 복사
var copy = group;
객체를 가리키는 변수(group)를 다른 변수(copy)에 할당하면 원본의 참조값이 복사되어 전달됨
이처럼 참조값을 복사해서 저장하고 있기 때문에 (group과 copy 모두 동일한 객체를 가리킴)
두개의 식별자가 하나의 객체를 공유하고 있는 것
때문에 원본 또는 사본 어느 한쪽이 객체를 변경하거나 수정하면 서로 영향을 받음
var person1 = {
name: 'son'
};
var person2 = {
name : 'son'
};
console.log(person1 === person2); // false
console.log(person1.name === person2.name); // true