원시 타입과 값 복사

string·number·boolean·undefined·null·bigint·symbol 7가지 원시 타입은 대입할 때 값 자체가 복사되어 변수끼리 서로 영향을 주지 않는다.

Seobway · · 6분

문제 상황

아래 두 코드는 같은 방식으로 대입했지만 결과가 다르다.

let a = 1;
let b = a;
b = 2;
console.log(a);        // 1 (변경되지 않음)

let x = { n: 1 };
let y = x;
y.n = 2;
console.log(x.n);      // 2 (함께 변경됨)

첫 번째는 원시 타입, 두 번째는 참조 타입이다. 대입할 때 복사되는 대상이 다르기 때문에 결과가 갈린다.


원시 타입의 종류

원시 타입(Primitive Type)은 변수에 값 자체가 저장되는 타입이다. ECMAScript 에는 7가지가 있다.

타입 예 비고
string "안녕" UTF-16 코드 유닛의 시퀀스
number 42, 3.14, NaN IEEE 754 배정밀도 부동소수점. 정수·실수 구분 없음
boolean true, false
undefined undefined 초기화되지 않은 변수의 기본값
null null 값이 없음을 명시적으로 나타냄
bigint 9007199254740993n Number.MAX_SAFE_INTEGER 를 넘는 정수
symbol Symbol("id") 유일한 값. 주로 충돌하지 않는 속성 키로 사용

이 7가지를 제외한 객체·배열·함수는 모두 참조 타입이다.

원시 값을 다른 변수에 대입하면 값이 복사된다. 두 변수는 각각 독립된 값을 가지므로
한쪽을 재할당해도 다른 쪽에 영향이 없다.

인터랙티브 다이어그램: 원시 값의 대입과 복사 (단계별로 재생할 수 있다)

  1. let a = 1 이 실행되어 a 에 값 1 이 저장된다.
  2. let b = a 는 a 의 값을 읽어 b 에 복사한다. 값이 두 개 존재한다.
  3. b = 2 는 b 에 새 값을 재할당한다.
  4. a 는 별도의 값이므로 영향을 받지 않는다.

원시 값의 불변성

원시 값은 불변(immutable)이다. 값의 일부를 수정하는 연산은 존재하지 않는다.

let s = "hello";
s[0] = "H";
console.log(s);            // "hello" (변경되지 않음)

s = "Hello";               // 변수에 새 문자열을 재할당

s[0] = "H" 는 원시 값에 속성을 쓰려는 시도이며, 비엄격 모드에서는 무시되고 엄격 모드에서는
TypeError 가 발생한다. toUpperCase() 같은 문자열 메서드도 원본을 수정하지 않고 새 문자열을 반환한다.
변수 s 에 다른 값을 재할당하는 것은 값의 수정이 아니라 변수가 가리키는 값의 교체다.


예제

typeof 로 각 값의 타입을 출력하고, 원시 값 복사가 독립적인지 확인한다.

const values = [
  "문자열", 42, true, undefined, null,
  9007199254740993n, Symbol("id"),
  {}, [], function () {},
];

for (const v of values) {
  console.log(String(typeof v).padEnd(10), "|", typeof v === "object" || typeof v === "function" ? "참조 타입" : "원시 타입");
}

// 원시 값 복사는 독립적이다
let a = 10;
let b = a;
b += 5;
console.log("a =", a, "/ b =", b);

출력에서 typeof null 이 "object" 로 나오는데, 이는 아래에서 설명한다.


자주 하는 실수


정리

원시 타입은 변수에 값 자체가 저장되는 7가지 타입(string, number, boolean, undefined, null,
bigint, symbol)이다. 대입 시 값이 복사되어 변수끼리 독립적이고, 값 자체는 수정할 수 없으며
재할당만 가능하다.

참고

  1. [1] Primitive — MDN Web Docs 용어 사전
  2. [2] JavaScript data types and data structures — MDN Web Docs
  3. [3] ECMAScript Language Types — ECMAScript 사양

관련 글