1. 값(Value)
값 = 식(expression)이 평가(evaluate)되어 생성된 결과
10 + 20 // 이 식이 평가되면 → 값 30
'hello' // 이것도 식 → 평가되면 문자열 값 'hello'
- 모든 값은 데이터 타입을 가짐 — 변수가 타입을 가지는게 아닌, 변수의 값이 타입을 가지는 것
- 모든 값은 메모리에 비트(bit)의 나열로 저장
같은 비트열이라도 타입에 따라 해석이 다름 → 데이터타입: 메모리에서 읽은 비트열의 해석을 결정
0100 0001
→ 숫자 타입으로 해석하면: 65
→ 문자 타입으로 해석하면: 'A'
2. 변수(Variable)
변수 = 값을 저장하기 위해 확보한 메모리 공간, 또는 그 공간을 가리키는 식별자(identifier)
var score = 100;
변수에는 값을 할당하는 것. 식(expression)을 할당하는 게 아님.
var score = 10 + 20;이라고 쓰면, 10 + 20이라는 식이 먼저 평가되어 값 30이 되고, 그 값 30이 변수에 저장됨.
3. 문(Statement)과 표현식(Expression)
문(statement) = 프로그램을 구성하는 기본 단위이자 최소 실행 단위
var x = 5; // 변수 선언문
if (x > 3) {} // 조건문
for (;;) {} // 반복문
표현식(expression) = 값으로 평가될 수 있는 문
5 + 3 // → 8
getName() // → 반환값
x = 10 // 할당 자체도 10으로 평가되는 표현식!
표현식인 문 vs 표현식이 아닌 문
브라우저 콘솔에서 직접 확인 가능: 값으로 평가되면 표현식 (표현식이 아닌 문은 값을 생성하지 않으므로 undefined가 암묵적으로 반환)
> var x = 5;
← undefined // 변수 선언문은 값을 생성하지 않음 → undefined
> x = 10;
← 10 // 할당 표현식은 값을 생성 → 10
> 1 + 2;
← 3 // 표현식이므로 평가 결과 출력
콘솔에서 undefined가 뜨느냐 마느냐의 차이 = 해당 문이 표현식인지 아닌지.
ASI (Automatic Semicolon Insertion)
JS 기능 중 문의 끝이라고 예측되는 지점에 세미콜론을 자동 삽입
'예측' 이기 때문에 틀리기도 함
function foo() {
return
{ name: 'bar' }
}
// ASI에 의해 return 뒤에 세미콜론 삽입!
// 실제로는 return; → undefined 반환
4. 데이터 타입
숫자 타입 — 모든 수는 실수
자바스크립트에는 하나의 숫자 타입(number)만 존재하고, 이는 IEEE 754 배정밀도 64비트 부동소수점 형식, 즉 모든 수는 '실수'

null과 undefined — 닮았지만 다름
둘 다 "값이 없음"을 나타내지만 의미가 다름:
undefined |
null |
|
|---|---|---|
| 의미 | 초기화되지 않음 (시스템적) | 의도적으로 비어있음 (개발자 의사) |
| 누가 쓰나 | JS 엔진이 자동으로 부여 | 개발자가 명시적으로 할당 |
| typeof | 'undefined' |
'object' (버그!) |
### typeof null은 왜 'object' 일까?
이는 JS 초창기(1995년)의 구현 버그. 수정 제안이 여러 번 있었지만, 이미 너무 많은 웹사이트가 이 동작에 의존 → 하위 호환성 때문에 영원히 수정 불가.
컨벤션: 변수에 "값이 없음"을 표현하고 싶다면 undefined가 아닌 null 사용하는게 좋다
-> 없는 값을 표현하고자 할때 이유를 알고 쓰는 것에서 개발자의 효능감이 높아진다고 생각 🙃
원시 타입은 변경 불가능(Immutable)
원시 타입(string, number, boolean, null, undefined, symbol, bigint)의 값 = 한번 생성되면 변경 불가 (immutable)
"변수의 값이 바뀐 것"과 "값 자체가 변경된 것"은 전혀 다른 이야기. 변수는 새로운 값을 가리킬 수 있지만, 메모리에 있던 'hello'라는 값 자체는 불변. 기존 'hello'는 어떤 변수도 참조하지 않게 되면 가비지 컬렉터가 회수.

이게 저번 주에 공부한 '변수' 에서 재할당 할때 다른 메모리 셀에 값을 저장하고 참조를 바꾸는 것과 일치하는 것 같다. 그러면 객체도 재할당 할때는 새로운 값에 하려나..? 이건 뒤에를 공부 해봐야 알겠다. ..
============================================================================
5. JS는 값을 어떻게 읽을까?
변수에 접근하면 JS 엔진은 값이 저장된 메모리 공간의 선두 셀을 찾아감. 그런데 몇 바이트를 읽어야 하는지 어떻게 알까?
심볼 테이블(Symbol Table)
엔진이 코드를 파싱/컴파일하는 단계에서 생성하는 식별자 관리 테이블:
식별자 이름 | 스코프 | 선언 키워드 | 저장 위치
────────────────────────────────────────────
a | 전역 | let | 슬롯 0번
b | 함수1 | const | 슬롯 1번
변수 이름 → 실제 저장 위치를 매핑하는 사전 같은 것. JS만의 개념이 아니라 거의 모든 언어의 컴파일러/인터프리터가 사용하는 범용 개념.
변수 슬롯(Variable Slot)
심볼 테이블이 가리키는 실제 값이 저장되는 고정 크기(64비트) 공간:
심볼 테이블 변수 슬롯 (메모리)
┌──────────┐ ┌─────────────────┐
│ a → 슬롯0 │ ──────────▶ │ 슬롯0: 64비트 값 │
│ b → 슬롯1 │ ──────────▶ │ 슬롯1: 64비트 값 │
└──────────┘ └─────────────────┘
태그드 포인터(Tagged Pointer) — V8 엔진의 트릭
V8(Chrome, Node.js)은 슬롯에 담긴 64비트 값의 마지막 1비트로 타입 판별:
- 마지막 비트
0→ Smi(Small Integer): 나머지 63비트가 곧 정수 값. 힙 할당 없이 슬롯 안에 직접 저장. - 마지막 비트
1→ 힙 객체 포인터: 나머지 63비트는 힙 메모리 주소. 그 주소의 객체 헤더에 상세 타입 정보 존재.
슬롯 값: ...0 → Smi (정수값이 슬롯에 직접 저장)
슬롯 값: ...1 → 힙 포인터 (문자열, 객체 등은 힙에서 관리)
이 1비트 트릭 덕분에 정수 연산은 힙 할당 없이 빠르게, 복잡한 객체는 힙에서 유연하게 관리. 성능과 유연성의 균형을 맞추는 영리한 설계.
참고: 태그드 포인터는 V8의 구현 방식. JS 스펙에 정의된 것이 아니므로, SpiderMonkey(Firefox)나 JavaScriptCore(Safari) 등은 다른 방식을 쓸 수 있음.
6. 동적 타이핑(Dynamic Typing)
자바스크립트의 변수는 선언 시점이 아니라 할당 시점에 타입 결정
7. 기타 — 줄바꿈 문자의 차이
텍스트 파일에서 "새로운 줄"을 나타내는 방식이 OS마다 다름:
| OS | 줄바꿈 문자 | ASCII 코드 |
|---|---|---|
| Windows | CR+LF (\r\n) |
13 + 10 |
| Unix/Linux/macOS | LF (\n) |
10 |
Git이 warning: LF will be replaced by CRLF 경고를 내는 이유가 바로 이것. 협업 시 git config core.autocrlf 설정으로 통일 권장.
'Frontend > javascript' 카테고리의 다른 글
| for문 읽다가 프로토타입 체인까지 온 건에 대하여 (0) | 2026.03.25 |
|---|---|
| [모던 Javascript DeepDive] 4. 변수 (0) | 2026.03.04 |
| [iframe 사용법 및 속성값 가이드] MDN 문서를 기반으로 작성한 가이드 문서 (2) | 2024.11.19 |
| [javascript] 생성자 함수는 어떤 과정으로 인스턴스를 생성할까? (2) | 2024.04.25 |
| [javascript] 생성자 함수에 의한 객체 생성 - 언제 필요하고 어떻게 사용하는가? (0) | 2024.04.18 |
댓글