[JavaScript] 원시 값과 참조 값

Rose Jang·2022년 11월 7일
0

Section 1

목록 보기
11/15

자바스크립트가 제공하는 데이터 타입은 크게 원시 타입(primitive type)참조 타입(reference type)으로 구분할 수 있다.



원시 타입 (primitive type)

원시 자료형

원시 값, 원시 데이터 타입은 객체가 아닌, 변수에 저장된 실제 값에 직접적으로 접근할 수 있는 단순한 데이터를 의미한다.

원시 타입에 해당하는 타입의 종류는 다음과 같다.

  • Number
  • String
  • Boolean
  • Null
  • Undefined
  • Biglnt
  • Symbol

원시 값변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장된다.

let a = 8;
let b;
b = 'str';

원시 값변경 불가능한 값(immutable value)이다. 하지만 이것은 값에 대한 설명으로, 변수에 값을 할당한 후 그것을 재할당하여 변수에 담긴 내용을 변경하는 것은 가능하다.

let word = 'hello world!';
word = 'Hi there!';
/* 원시 값을 할당한 변수에 재할당하면 재할당 이전의 원시 값을 변경하는 것은 아니고, 
새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장 후 변수가 새롭게 재할당한 값을 가리키는 것이다. */

변수의 상대개념인 상수는 재할당이 금지된 변수를 말한다. 변수는 언제든지 값을 변경할 수 있지만 상수는 단 한번만 할당이 가능하므로 변수 값을 변경할 수 없다.
하지만 상수와 변경 불가능한 값을 동일시 하는것은 곤란하다. 상수는 재할당이 금지된 변수일 뿐이다.

const num1 = 123;
num1 = 456; // 에러 발생

값 전달

원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다.
말 그대로 "값(value) 그대로" 저장, 할당되고 복사된다.

let a = 2;
let b;
b = a;

console.log(a, b); // 2 2
console.log(a === b); //true

이 때 변수 a와 b는 숫자 값 2를 갖는다는 점에서는 동일하다. 하지만 a와 b의 값 2는 다른 메모리 공간에 저장된 별개의 값이다.




참조 타입 (reference type)

참조 자료형

원시 값을 할당한 변수는 원시 값 자체를 값으로 갖는다. 하지만 객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값(reference value) 에 접근할 수 있다.


참조 값생성된 객체가 저장된 메모리 공간의 주소이다.

참조 값을 변수에 할당할 때는 변수에 값이 아닌 보관함의 주소(reference)를 저장한다.
그렇기 때문에 기존에 고정된 크기의 보관함이 아니라, 동적으로 크기가 변하는 특별한 보관함을 사용할 수 있다.

자바스크립트에서 원시 자료형이 아닌 모든 것은 참조 자료형이다. 아래 세 가지가 대표적인 참조 자료형이다.

  • 배열 ([])
  • 객체 ({})
  • 함수(function(){})

원시 값을 할당한 변수의 경우 "변수는 ~값을 갖는다"와 같이 표현하지만, 객체를 변수에 할당한 경우 "변수는 객체를 참조하고 있다" 또는 "변수는 객체를 가리키고 있다"라고 표현한다.

let user = {
  name: 'John';
}

// user 변수는 객체 {name: 'John'}을 참조하고 있다.

원시 값은 변경 불가능한 값이므로 원시 값을 갖는 변수의 값을 변경하려면 재할당 밖에는 방법이 없다.
하지만 객체는 변경 가능한 값이기 때문에 객체를 할당한 변수는 재할당 없이 프로퍼티를 동적으로 추가하거나, 프로퍼티 값을 갱신하거나 프로퍼티를 삭제하는 등 객체를 직접 변경할 수 있다.

// 프로퍼티 값 갱신
user.name = 'Jack';

// 프로퍼티 동적 생성
user.age = 20;
user.adress = 'Manhattan';

// 프로퍼티 삭제
delete user.adress;

console.log(user); // {name: 'Jack', age: 20}

값 전달

원본 객체(배열)을 사본에 할당하면 원본의 참조 값을 복사해서 사본에 전달한다. 이 때 원본과 사본은 저장된 메모리 주소는 다르지만 동일한 참조 값을 갖는다.

원본과 사본이 모두 동일한 객체를 가르킨다. 두 개의 식별자가 하나의 객체(배열)을 공유한다는 것을 의미한다.

따라서 원본 또는 사본 중 어느 한쪽에서 객체를 변경하면, 서로 영향을 주고받는다.

let colors = ['red', 'green', 'blue'];

let copy = colors;

copy.push('black');
colors.unshift('white');

console.log(colors); // ['white', 'red', 'green', 'blue', 'black']
console.log(copy); // ['white', 'red', 'green', 'blue', 'black']

비교

=== 연산자를 통해 객체(배열)등을 할당한 변수를 비교하면 참조 값을 비교하고, 원시 값을 할당한 변수를 비교하면 원시 값을 비교한다.

let user1 = {name: 'John'};
let user2 = {name: 'John'};

console.log(user1 === user2); // false
console.log(user1.name === user2.name); // true

user1변수와 user2변수가 가리키는 객체는 내용은 같지만 다른 메모리에 저장된 별개의 객체이기 때문에 두 변수의 참조 값은 전혀 다른 값이다. 따라서 결과는 false이다.

하지만 user1.nameuser2.name은 프로퍼티 값을 참조하기 때문에 두 표현식 모두 원시 값 'John'으로 평가하여 결과는 true이다.

0개의 댓글