JavaScript는 원시 타입과 참조 타입이라는 두가지 자료형을 제공하며 Object
를 제외한 모든것들은 Primitive한 성격을 갖고 있다.
원시 타입의 데이터는 변수에 할당이 될 때 메모리 상에 고정된 크기로 저장이 되고 해당 변수가 원시 데이터 값을 보관한다. 원시 타입 자료형은 모두 변수 선언, 초기화, 할당 시 값이 저장된 메모리 영역에 직접적으로 접근한다. 즉, 변수에 새 값이 할당이 될 경우, 변수에 할당된 메모리 블럭에 저장된 값을 바로 변경한다.
Boolean
number
String
null
undefined
각 변수 간에 원시 타입 데이터를 복사할 경우, 데이터의 값이 복사된다.
var x = 100;
var y = x;
x = 99; //100
console.log(y); // 100;
데이터의 값을 복사하기 때문에 console을 찍기 전, x를 99로 바뀌었지만 이전의 값인 100을 복사해두었기 때문에 100이 찍히는 것을 볼 수 있다.
참조 타입의 데이터는 크기가 정해져 있지 않고 변수에 할당이 될 때 값이 직접 해당 변수에 저장될 수 없으며 변수에는 데이터에 대한 참조만 저장 된다. 변수의 값이 저장된 힙 메모리의 주소값을 저장 한다. 참조 타입은 변수의 값이 저장된 메모리 블럭의 주소를 가지고 있고 자바스크립트 엔진이 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근 한다.
Object
( array, function, object )각 변수 간에 참조 타입 데이터를 복사할 경우, 데이터의 참조가 복사된다.
var x = { count : 100 };
var y = x;
x.count = 99;
console.log(y); // {count : 99}
변수 x
와 y
는 동일한 참조를 담고 있다. 따라서 동일한 객체를 가리키게 된다.
var list1 = [1, 2, 3]; // 메모리 주소 : 8765e 라고 가정
var list2 = [1, 2, 3]; // 메모리 주소 : 9524d 라고 가정
var isSame = list1 === list2; //메모리 주소 기준으로 보면 8765e === 9524d
console.log(isSame); // false
list1
, list2
안의 요소는 같지만 배열을 새롭게 만들어 변수에 담고 있기 때문에 각자 새로운 메모리 위치를 만들어 저장하고 그 위치를 참조하여 변수에 해당 위치값을 저장하는 것 과 같다. 따라서 결과는 false
가 된다.
var list3 = [ 1, 2, 3];
var list4 = list3;
var isSame = list3 === list4;
console.log(isSame); // true
위의 예제와는 다르게 새롭게 배열을 생성하지않고 list3
의 위치값을 그대로 list4
에 넣는 것이기 때문에 위치값이 같은 경우 라고 할 수 있다. 따라서 결과는 true
가 된다.
var updateAge = function () {
this.age++;
}; // '메모리 주소 : 4737d' 라고 가정
var son = {
age : 3,
growUp : updateAge()
};
var daugther = {
age : 7,
growUp : updateAge()
};
var mother = {
age : 38,
growUp : updateAge(),
children : [ son, daugther ]
};
var father = {
age : 38,
growUp : updateAge(),
wife : mother,
children : [ son, daugther ]
};
// 테스트1
if (father.growUp === son.growUp) {
console.log('성장 가능'); // 성장 가능
}
// 테스트2
if (father.children === mother.children) {
console.log('부부!'); // false로 console이 찍히지 않음
}
테스트1의 경우, updateAge
라는 변수의 데이터 값으로 함수의 위치값을 저장했다. 가상 메모리 주소가 4737d
라는 가정하에 object
는 동일한 데이터의 위치값을 저장하므로 father.growUp
과 son.growUp
의 값은 같은 값이 된다. 따라서 결과는 true
로 console
에 '성장 가능'이 찍히게 된다.
테스트2의 경우, 똑같은 변수들이 담겨있지만 객체 내에서 배열을 새롭게 만들어 mother.children
과 father.children
은 서로 다른 위치값을 할당을 새롭게 할당받았기 때문 에 위치값이 다르게 된다. 따라서 결과는 false
로 console
에 아무것도 찍히지 않게 된다.