원시 타입(primitive type)데이터란 number, string, boolean과 같이 고정된 저장 공간을 차지하는 것을 뜻합니다.
// 원시 타입의 종류 => number, boolean, null, undefined, string
반면 배열과 객체는 저장공간이 계속 늘어날 수 있습니다.
(배열과 객체의 저장공간이 계속 늘어날 수 있는 이유는 특별한 저장 공간을 사용하기 때문입니다.)
이 특별한 저장 공간을 주소 타입(reference type)데이터라고 합니다. 배열, 객체, 함수에서 이런 특별한 저장 공간(heap)을 사용합니다.
원시 자료형이 할당될 때에는 변수에 값(value)가 담기고, 참조 자료형이 할당될 때는 보관함의 주소(reference)가 담겨요.
원시 자료형은 모두 하나의 데이터를 담고 있습니다. (중요한 부분은 "하나"라는 점입니다. "하나"만 담을 수 있기 때문에 원시적이라고 얘기합니다."
원시 자료형 값은 immutable 하지만 변수에 다른 데이터를 할당할 수 있습니다.
ex)
let word = "Hello World";
word = "Hello CodeStates";
console.log(word); // Hello CodeStates 출력
하지만 word를 const로 선언했을 경우에는 재할당이 불가능하고 에러가 발생합니다.
참조 자료형은 하나의 주제가 있고, 여러 개의 데이터를 가지고 있을 수 있습니다.
원시자료형도 중요하지만 참조 자료형에 대한 깊은 이해가 필요합니다.
우선 배열 [] 객체 {} 함수 function(){} 이 대표적인 참조 자료형입니다.
reference는 참조라는 뜻이지만 컴퓨터 공학에서는 변수가 가리키고 있는 데이터를 의미합니다.
(배열과 객체를 사용하는 이유는 대량의 데이터를 쉽게 다루기 위해서 사용하는 것입니다. 데이터를 추가하고 삭제하는 것에 따라 크기가 달라지기 때문입니다.)
원지 자료형과 참조 자료형의 특징 복습
ex)1
let x = 2;
let y = x;
y = 3;
console.log(x) // 2를 출력한다.
원시 자료형은 하나의 값만 가질 수 있어서 원시 자료형이라고 부릅니다. 변수 x를 y에 할당해도 x의 값은 영향을 받지 않습니다.
ex)2 참조 자료형
let x = {foo: 3};
let y = x;
y.foo = 2;
console.log(x.foo); // 2가 출력됩니다.
참조 자료형 문제입니다. 변수에 데이터가 저장되는 곳의 주소가 할당 됩니다.
let x = {foo: 3}; 은 x에서 foo라는 주소를 바라보고 있는 것입니다.
let y = x 를 통해 y도 {foo: 3}이라는 걸 바라보고 있습니다.
이때 y.foo = 2; 를 할 경우 foo 라는 주소에 있던 3이 2로 변경됩니다.
따라서 같은 곳을 바라보고 있던 x.foo 도 2가 됩니다.
ex)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
원시 자료형은 값이 같으면 같습니다. 하지만 크기가 수시로 변하는 것을 처리하는 원시 자료형에서는 값이 같다고 주소가 같은 것이 아닙니다.
같은 [1,2,3] 을 가지고 있을지라도 다른 곳의 heap 을 사용하고 있기 때문에 true가 나오지 않습니다.
[] === [] false가 출력됩니다.
따라서 3번 4번 [], {} 배열과 객체는 false를 반환합니다.
ex)4 코드가 실행된 후, x.foo의 값을 구하시오.
let x = {foo: 3};
let y = x;
y = 2;
let y = x 를 통해 y도 x의 주소를 할당받았습니다. 이걸 다시 y에다가 2를 할당해줬습니다.
이 과정에서 y는 foo 라는 주소를 사용하지 않았기 때문에 아무 영향을 미치지 않습니다.
x.foo를 조회해도 x.foo 값은 그대로 3입니다.
ex)5 코드 실행 후 myArray 값을 알아보자. (잘 봐야함)
let myArray = [2,3,4,5];
let ourArray = myArray;
ourArray[2] = 25;
ourArray = undefined;
변수 ourArray = myArray, ourArray에 myArray라는 주소값이 할당되었습니다.
이때 ourArray[2] = 25를 통해서 myArray[2] 가 25로 변경됩니다.
이후 ourArray = undefined를 할당했습니다. 그렇다고 myArray가 사라지는 건 아닙니다.
따라서 myArray를 출력할 경우 [2,3,25,5] 라는 결과를 가져옵니다.
ex)6 코드가 실행된 후, player.score 의 값은 무엇일까?
let player = {score: 3};
function doStuff(obj){
obj.score = 2;
}
doStuff(player);
doStuff 변수에 player를 전달하여 호출합니다.
함수를 통해 obj.score가 player.score로 변경됩니다. 이때 할당 된 값이 2입니다.
따라서 player.score 도 2를 출력합니다.
ex)7 코드가 실행된 후, score의 값은 무엇일까요?
let score = 80;
function doStuff(value){
value = 90;
}
doStuff(score);
function(){} 의 경우 참조 자료형입니다. 따라서 함수에서 어떤 일이 발생해도 score에 할당된 초기값 80은 그대로 유지됩니다.