본문 바로가기

코드잇 스터디

[JS기초문법] 원시타입 vs 참조타입

원시타입 vs 참조타입

원시 타입 (Primitive Types)

// 5가지 원시 타입
let num = 10;              // Number
let str = 'Hello';         // String
let bool = true;           // Boolean
let nothing = null;        // null
let notDefined = undefined; // undefined

특징: 값 자체가 저장됨

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

b = 20;     // b만 변경

console.log(a); // 10 (변하지 않음)
console.log(b); // 20
메모리 구조:

a: [10]
b: [10] → [20]

각각 독립적인 공간에 저장
function changeValue(x) {
    x = 100;
    console.log('함수 안:', x);
}

let num = 10;
changeValue(num);
console.log('함수 밖:', num);

// 출력:
// 함수 안: 100
// 함수 밖: 10 (변하지 않음)

 

참조 타입 (Reference Types)

// 객체, 배열, 함수
let obj = { name: '홍길동' };
let arr = [1, 2, 3];
let func = function() { };

특징: 참조(주소)가 저장됨

만들어질때 heap에다가 참조 주소값이 저장됨 (참조값)

let person1 = { name: '홍길동', age: 25 };
let person2 = person1;  // 참조가 복사됨

person2.age = 30;       // person2를 수정

console.log(person1.age); // 30 (같이 변경됨!)
console.log(person2.age); // 30
메모리 구조:

person1: [주소: 0x001]
person2: [주소: 0x001]  (같은 주소)

0x001: { name: '홍길동', age: 25 → 30 }

같은 객체를 가리킴
function changeObject(obj) {
    obj.name = '김철수';
    console.log('함수 안:', obj.name);
}

let person = { name: '홍길동' };
changeObject(person);
console.log('함수 밖:', person.name);

// 출력:
// 함수 안: 김철수
// 함수 밖: 김철수 (같이 변경됨!)

얕은 복사 vs 깊은 복사

얕은 복사 (Shallow Copy):

한 단계만 복사하고, 내부 참조는 그대로 공유함

- 1depth까지만 복사

- 객체/배열 안의 객체는 같은 참조 (shared reference)

- 껍데기만 새로, 속은 공유

ex) 일반 상태 업데이트 (React 등)

const original = { a: 1, b: { c: 2 } };
const copy = { ...original };

copy.b.c = 999;

console.log(original.b.c); // 999 😱 (같이 바뀜)

 

깊은 복사 (Deep Copy):

모든 중첩 객체까지 완전히 새로 복사

- 완전히 독립된 객체

- 참조 공유 없음

- 상대적으로 비용 크다

- 속까지 전부 새로

ex) 중첩 구조까지 완전히 분리 필요

const original = { a: 1, b: { c: 2 } };
const copy = structuredClone(original);

copy.b.c = 999;

console.log(original.b.c); // 2 ✅ (안 바뀜)

Truthy vs Falsy

Falsy 값

이 8가지만 Falsy:

false, 0, -0, 0n, '', null, undefined, NaN 나머지는 모두 Truthy!

// 1. false
if (false) {
    console.log('실행 안 됨');
}

// 2. 0
if (0) {
    console.log('실행 안 됨');
}

// 3. -0
if (-0) {
    console.log('실행 안 됨');
}

// 4. 0n (BigInt 0)
if (0n) {
    console.log('실행 안 됨');
}

// 5. '' (빈 문자열)
if ('') {
    console.log('실행 안 됨');
}

// 6. null
if (null) {
    console.log('실행 안 됨');
}

// 7. undefined
if (undefined) {
    console.log('실행 안 됨');
}

// 8. NaN (Not a Number)
if (NaN) {
    console.log('실행 안 됨');
}

 

Truthy

if (true) { }              // ✅
if (1) { }                 // ✅
if (-1) { }                // ✅
if ('hello') { }           // ✅
if ('0') { }               // ✅ 문자열 '0'은 Truthy
if (' ') { }               // ✅ 공백 문자열도 Truthy
if ([]) { }                // ✅ 빈 배열도 Truthy
if ({}) { }                // ✅ 빈 객체도 Truthy
if (function(){}) { }      // ✅

AND와 OR 연산자

a && b

1. a를 평가

2. a가 Falsy면 → a 반환 (b는 보지도 않음)

3. a가 Truthy면 → b 반환

=> 왼쪽부터 오른쪽까지 읽어나가면서 falsey한 값에 멈춤 (아니면 끝에 값 출력)

// Falsy && 무엇
console.log(0 && 100);        // 0
console.log('' && 'hello');   // ''
console.log(null && true);    // null

// Truthy && 무엇
console.log(1 && 100);        // 100
console.log('hello' && 'world'); // 'world'
console.log(true && 'yes');   // 'yes'

// 여러 개 연결
console.log(1 && 2 && 3);     // 3 (마지막까지 감)
console.log(1 && 0 && 3);     // 0 (0에서 멈춤)

 

a || b

1. a를 평가

2. a가 Truthy면 → a 반환 (b는 보지도 않음)

3. a가 Falsy면 → b 반환

=> 왼쪽에서 오른쪽까지 읽어나가면서 truthy한 값에 멈춤 (아니면 끝에 값에 출력)

// Truthy || 무엇
console.log(1 || 100);        // 1
console.log('hello' || 'world'); // 'hello'
console.log(true || false);   // true

// Falsy || 무엇
console.log(0 || 100);        // 100
console.log('' || 'default'); // 'default'
console.log(null || 'value'); // 'value'

// 여러 개 연결
console.log(0 || '' || 3);    // 3 (처음 Truthy)
console.log(0 || null || ''); // '' (모두 Falsy면 마지막)

'코드잇 스터디' 카테고리의 다른 글

[JS기초문법] for...of, for...in  (0) 2026.04.06
[Git] Git에 대해서  (0) 2026.04.01
[실용적 유닉스 커맨드]  (0) 2026.03.29
[HTML] Hero vs Banner  (0) 2026.03.24
[CSS] reset.css에 대해서  (0) 2026.03.24