JavaScript | 원시 자료형과 참조 자료형

SURI·2021년 11월 24일

1. 개념


원시 자료형과 참조 자료형

원시 자료형(primitive type)

let name; // name 이라는 이름이 붙은 개인 사물함이 생긴다.
name = 'suri'; // name 사물함을 찾아 'suri'라는 값을 넣어준다.

let age;
age = '22';
age = name;
console.log(name); // name의 값은 변하지 않는다.
  • 변수에 값 자체가 담긴다.
  • 고정된 저장 공간을 차지하는 데이터다.
  • number, boolean, (null), undefined, string symbol 타입이 여기에 해당한다.
  • 새로운 변수를 만들어 기존 변수의 값을 할당해도 (복사) 기존의 변수 값은 바뀌지 않는다.

참조 자료형(reference type)

let arr = [1, 2];
let newArr = arr; // 주소 값이 복사되므로 같은 배열을 가리키게 된다.
newArr[0] = 3;
arr[0] = 3; // 원본 배열의 값도 변경이 된다. 
  • 참조 자료형이 할당될 때는 보관함의 주소(reference)가 담긴다.
  • 특별한 저장 공간을 사용하기 때문에 저장공간이 유동적으로 계속 늘어날 수 있다.
  • 사물함 아래 heap이라는 빈 공간을 만들고, 사물함에는 주소를 담는다. 그리고 해당 주소에 값을 줄줄이 담는다.
  • 배열, 객체, 함수 타입이 여기에 해당한다.
  • 자바스크립트에서는 원시 자료형이 아닌 모든 것은 Object이다.
  • 새로운 변수를 만들어 기존 변수 값을 할당하면 주소값이 복사 된다. 그 상태에서 새로운 변수의 값을 변경하면 기존 변수의 값도 바뀌게 된다.

원시자료형 심화

  • 원시 자료형은 데이터가 하나의 정보만을 담고 있다. 옛날에는 데이터 저장소 용량이 제한되어 변수 하나에 하나의 원시 자료형 밖에 담을 수 밖에 없었다.
  • 원시 자료형이 담기는 보관함의 크기는 고정하는 것이 합리적이다.
  • 원시 자료형은 값 자체에 대한 변경은 불가능하지만, 변수에 다른 데이터를 할당할 수는 있다.
  • 변수 하나에 값 하나 원시자료형은 심플하다.
let words = "beautiful world!"
words = "wonderful world!" // 재할당. const 키워드로 선언하면 재할당 불가

참조자료형 심화

  • 변수에 넣을 수 있는 데이터의 크기가 제한되기 때문에, 자료 구조를 따로 구현했다. 배열과 객체같이 데이터의 크기가 동적으로 변하는 특별한 데이터 보관함이 필요했다.
  • 참조 자료형에는 하나의 데이터가 아닌 여러 데이터가 담기게 된다. 어떻게?
  • 동적으로 변하는 특별한 데이터 보관함(heap)을 만들고 변수에는 그 보관함을 찾아갈 수 있는 주소를 변수에 저장한다.
  • 변수가 가리키고 있는 데이터를 참조한다고 해서 참조 자료형이다. 주소를 참조하여 그 데이터를 비로소 읽어온다.
  • 대량의 데이터의 경우 고정된 데이터 공간을 사용하는 것은 비효율적이다.
  • 참조 자료형은 기존에 고정된 크기의 보관함이 아니라, 동적으로 크기가 변하는 특별한 보관함을 사용할 수 있다.
let x = { foo: 3 };
let y = x;
y.foo = 2; // x와 y는 똑같은 데이터를 바라보고 있다.

let player = { score: 3 };
function doStuff(obj) { 
  obj.score = 2;
}

doStuff(player); 
// 함수가 호출되면 (실행되면) 매개변수 obj에 player의 값이 할당된다. 즉, { score: 3 }의 주소값이 할당된다.

console.log('codestates' === 'codestates');
console.log(3.14 === 3.14);
console.log([1,2,3] === [1,2,3]);
console.log({ foo: 'bar' } === { foo: 'bar' });

  • 'codestates' 이 문자열 하나는 무엇을 의미할까? 변수에 담기지 않은? 이 문제 좀 헷갈렸다.
  • 참조 자료형의 ===(strict equality)는 주소값이 같은지를 확인합니다. 그렇기 때문에 두 참조 자료형의 주소값은 다르다고 판단을 내릴 수 있습니다. 배열([])과 객체({})등 참조 자료형을 읽을 때, 미리 주소값과 메모리 값을 잡아둔다고 생각하면 편합니다. 그러므로 [] === [] 도 true가 나오지 않는 것이죠.

변수의 선언은 메모리에 자리를 잡는 것이고, 값의 할당은 메모리에 값을 채우는 것

2. 에러로그


참조자료형 변수에서 그 사물함 자체의 값을 바꾸는지, 특별 보관함의 값을 가리키는지 구분한다.

let myArray = [2, 3, 4, 5];
let ourArray = myArray;
ourArray[2] = 25;
ourArray = undefined; 
// 이제 변수 ourArray에 원시 자료형 undefined가 할당되었기 때문에, myArray에 접근할 수 없습니다.

매개변수 value에 전달하는 인자가 원시자료형일 때?

let score = 80;
function doStuff(value) {
  value = 90;
}
doStuff(score);
  • 변수 score의 값은 원시 자료형이기 때문에 주소값을 전달하지 않고, 값 자체를 복사하여 전달한다. 그래서 함수에서 발생하는 일과 관계 없이 score의 초기 할당된 값을 유지한다.

3. 질문


  • checkpoint 7번 다시 한 번 봐야 할 것 같다. 완벽하게 이해하지 못하는 듯.
profile
Every step to become a better version of me 🚶‍♂️ 블로그 이사중

0개의 댓글