자바스크립트의 데이터 타입은 크게 원시값(Primitive) 과 참조값(Reference) 으로 나뉩니다. 면접에서 "원시값과 참조값의 차이"를 물어보면, 단순히 목록을 나열하는 것보다 메모리에 어떻게 저장되는지 를 설명할 수 있어야 합니다.

원시 타입 7가지

자바스크립트의 원시 타입은 총 7개입니다.

JS
// 원시 타입 목록
const str = "hello";       // string
const num = 42;            // number
const big = 9007199254740991n; // bigint
const bool = true;         // boolean
const undef = undefined;   // undefined
const nul = null;          // null
const sym = Symbol("id");  // symbol

원시값의 핵심 특징은 불변(immutable) 이라는 점입니다. 문자열을 "변경"하는 것처럼 보여도 실제로는 새로운 문자열이 만들어집니다.

JS
let greeting = "hello";
greeting = "world"; // "hello"가 변경된 게 아니라, 새 문자열 "world"가 생성됨

참조 타입

원시 타입이 아닌 모든 것은 참조 타입입니다.

JS
const obj = { name: "심정훈" };  // 객체
const arr = [1, 2, 3];           // 배열 (사실 객체)
const fn = () => {};             // 함수 (사실 객체)
const date = new Date();         // Date (사실 객체)

메모리 저장 방식의 차이

면접에서 가장 자주 물어보는 포인트입니다.

원시값 — 스택에 값 자체를 저장

JS
let a = 10;
let b = a; // 값이 복사됨

b = 20;
console.log(a); // 10 — a는 영향 없음

b = a를 실행하면 a값 10이 복사 되어 b에 저장됩니다. 이후 b를 변경해도 a에는 영향이 없습니다.

참조값 — 힙에 데이터, 스택에 주소를 저장

JS
let obj1 = { name: "홍길동" };
let obj2 = obj1; // 주소가 복사됨

obj2.name = "이순신";
console.log(obj1.name); // "이순신" — obj1도 같이 변경됨!

obj2 = obj1은 객체를 복사한 게 아니라 같은 힙 메모리 주소 를 공유합니다. 그래서 하나를 수정하면 다른 쪽에도 반영됩니다.

비교 연산의 차이

JS
// 원시값: 값으로 비교
"hello" === "hello" // true

// 참조값: 주소로 비교
{ name: "a" } === { name: "a" } // false — 서로 다른 객체

면접에서 "빈 객체끼리 ===로 비교하면 왜 false인가요?"라는 질문이 나올 수 있습니다. 답은 참조값은 메모리 주소를 비교 하기 때문입니다.

함수 인자 전달

자바스크립트는 항상 값에 의한 전달(pass by value) 입니다. 다만 참조값의 경우 "값"이 메모리 주소이므로 마치 참조 전달처럼 보입니다.

JS
// 원시값 전달 — 외부 변수 변경 불가
function changeValue(x) {
  x = 100;
}
let num = 10;
changeValue(num);
console.log(num); // 10

// 참조값 전달 — 내부 프로퍼티 변경 가능
function changeName(obj) {
  obj.name = "변경됨";
}
let person = { name: "원본" };
changeName(person);
console.log(person.name); // "변경됨"

// 하지만 재할당은 외부에 영향 없음
function replaceObj(obj) {
  obj = { name: "새 객체" }; // 새 주소를 가리킴
}
replaceObj(person);
console.log(person.name); // "변경됨" — 재할당은 외부에 영향 없음

typeof 연산자의 함정

JS
typeof "hello"    // "string"
typeof 42         // "number"
typeof true       // "boolean"
typeof undefined  // "undefined"
typeof null       // "object"  ← 유명한 버그!
typeof {}         // "object"
typeof []         // "object"  ← 배열도 object
typeof function(){} // "function"

typeof null === "object"는 자바스크립트 초기 구현의 버그인데, 하위 호환성 때문에 수정되지 않았습니다. 배열인지 확인하려면 Array.isArray()를 사용해야 합니다.

깊은 복사 vs 얕은 복사

참조값을 안전하게 복사하려면 깊은 복사가 필요합니다.

JS
const original = { a: 1, nested: { b: 2 } };

// 얕은 복사 — 1단계만 복사
const shallow = { ...original };
shallow.nested.b = 999;
console.log(original.nested.b); // 999 — 중첩 객체는 공유됨

// 깊은 복사 — structuredClone (모던 브라우저)
const deep = structuredClone(original);
deep.nested.b = 0;
console.log(original.nested.b); // 999 — 영향 없음

면접 포인트 정리

구분원시값참조값
저장 위치스택힙 (스택에 주소 저장)
복사값 복사주소 복사 (얕은 복사)
비교값 비교주소 비교
불변성불변가변
typeof정확함 (null 제외)"object"

**기억하기 **: 원시값은 "값 자체"를 다루고, 참조값은 "주소"를 다룹니다. 면접에서 이 차이를 메모리 관점으로 설명할 수 있으면 기본기가 탄탄하다는 인상을 줄 수 있습니다.

댓글 로딩 중...