원시타입 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 |