:객체가 아니면서 method를 가지지 않는 6가지의 타입
원시 자료형은 모두 '하나'의 정보, 즉 데이터를 담고있음.
변수에는 하나의 데이터만 담음.
원시 자료형은 값 자체에 대한 변경이 불가능(immutable)하지만,
변수에 다른 데이터를 할당할 수는 있음.
:하나의 데이터가 아닌 여러 데이터가 담기게 됨
변수에는 특별한 데이터 보관함을 찾아갈 수 있는 주소가 담겨있음
이 주소를 따라가 보면 특별한 데이터 보관함을 찾을 수 있는데, 이 특별한 데이터 보관함에서는 자기 마음대로 사이즈를 늘렸다가 줄였다가 함.("동적(dynamic)으로 변한다"라고 하기도 한다.)
이처럼 데이터는 별도로 관리되고, 우리가 직접 다루는 변수에는 주소가 저장되기 때문에 reference data type이라고 불림.
이런 특별한 데이터 보관함을 heap이라고도 부름.
원시 자료형이 할당될 때에는 변수에 값(value) 자체가 담기고,
참조 자료형이 할당될 때는 보관함의 주소(reference)가 담김.
그래서 참조 자료형은 기존에 고정된 크기의 보관함이 아니라,
동적으로 크기가 변하는 특별한 보관함을 사용할 수 있음.
check! 1
let first = [10, 20, 30, 40];
let second = first;
second[0] = 5;
first === second 의 결과는 True이다.
--
second는 first가 가지고 있는 주소를 그대로 가지고 있습니다. 값만 복사했다면 second의 0번째 인덱스에 있는 요소를 변경하면 first는 변경되지 않겠지만, 주소를 공유하고 있기 때문에 first도 똑같이 변경됩니다. 이런 특징을 가지고 있는 자료형을 참조 자료형이라고 합니다.
check! 2
let x = { foo: 3 };
let y = x;
y.foo = 2;
console.log(x.foo); // 2
--
let y = x;
변수 x를 변수 y에 할당하는 경우, 변수 x의 값은 참조 자료형이기 때문에 x의 값 { foo: 3 }의 주소를 y에 할당합니다.
이 상태는 변수 x와 변수 y에 모두 같은 { foo : 3 } 이라는 객체의 주소를 바라보고 있습니다.
y.foo = 2;
y.foo = 2, 값이 3이었던 y.foo에 2를 할당을 했습니다. 그러면 x.foo는 무엇일까요? 현재는 같은 주소를 바라보고 있는 y.foo가 2로 변경이 되었으니, 같은 곳을 바라보고 있었던 x.foo도 2가 되어야 합니다.
check! 3
console.log('codestates' === 'codestates'); //true
console.log(3.14 === 3.14); //true
console.log([1,2,3] === [1,2,3]); //false
console.log({ foo: 'bar' } === { foo: 'bar' }); //false
--
참조 자료형은 heap이라는 별도의 메모리 저장 공간을 사용합니다.
참조 자료형의 ===(strict equality)는 주소값이 같은지를 확인합니다. 그렇기 때문에 두 참조 자료형의 주소값은 다르다고 판단을 내릴 수 있습니다.
console.log([1,2,3] === [1,2,3]);
컴퓨터가 위 코드를 읽으면서, 이미 두 개의 heap 저장 공간의 주소를 확보했습니다. 다만 우리는 눈으로 확인하지 못할 뿐입니다. 배열([])과 객체({}) 등 참조 자료형을 읽을 때, 미리 주소값과 메모리 값을 잡아둔다고 생각하면 편합니다. 그러므로 [] === [] 도 true가 나오지 않는 것이죠.
check! 4
let x = { foo: 3 };
let y = x;
y = 2;
console.log(x.foo); // 3
--
let y = x;
여기서 변수 y는 x의 주소값을 할당받았습니다.
y = 2;
하지만 다시 2를 할당받았습니다.
이 과정 중에서 참조 자료형 { foo : 3 } 에는 아무런 영향을 미치지 않았기 때문에, x.foo를 조회해도 그대로 3이 나오게 됩니다.
이거는 참조자료형에 영향을 줘서 바뀐건가..? 참조자료형에 원시값을 재할당하면 원본주소?에는 영향을 안주고?.......
좀더 공부해봐야할듯...........
check! 5
let myArray = [2, 3, 4, 5];
let ourArray = myArray;
ourArray[2] = 25;
ourArray = undefined;
console.log(myArray); // [2, 3, 25, 5]
--
let ourArray = myArray;
변수 ourArray에 myArray의 주소값이 할당되었습니다.
ourArray[2] = 25;
ourArray 주소값에 위치한 배열의 2번째 요소를 25로 변경합니다. ourArray와 myArray의 주소값은 같음으로 현재 myArray는 [2, 3, 25, 5] 입니다.
ourArray = undefined;
이제 변수 ourArray에 원시 자료형 undefined를 할당함,
ourArray에 할당된 주소값은 없어지고 undefined가 재할당한것.
그러면 myArray에 접근할 수 없음. 하지만 myArray는 그대로 [2, 3, 25, 5].
check! 6
let score = 80;
function doStuff(value) {
value = 90;
}
doStuff(score)
console.log(score); // 80
--
doStuff(score)
함수 doStuff에 score의 값을 인자로 전달하여 실행합니다.
function doStuff(value) {
value = 90;
}
매개변수 value에 score의 값 80이 전달되고,
value = 90에서 value에 90이 할당됩니다.
다만 변수 score의 값 80은, 참조 자료형이 아니기 때문에 주소값을 전달하지 않고, 값 자체를 복사하여 전달하게 됩니다. 그래서 함수에서 어떤 일이 발생했던가와 관련이 없이 score는 초기에 할당된 값 80이 그대로 유지됩니다.