JavaScript 코드는 크게 두 가지 문법적 카테고리로 나뉩니다: Expression(표현식)과 Statement(문장). 이 둘의 차이를 이해하는 것은 JavaScript를 깊이 있게 이해하는 핵심입니다.
핵심 차이점
표현식(Expression)은 문장(Statement)처럼 동작할 수 있지만, 문장(Statement)은 표현식(Expression)처럼 동작할 수 없다.
1
2
3
4
5
| // Expression은 Statement가 될 수 있음
1 + 1; // 표현식 문장 (Expression Statement)
// Statement는 Expression이 될 수 없음
if (true) {} // 값으로 사용 불가
|
Expression (표현식)
정의
표현식은 값을 산출해내는 코드를 의미합니다. 값이 도출되기 때문에 함수의 인자로 전달할 수 있습니다.
1
2
3
4
5
6
7
8
| // 모두 표현식
1;
5 + 5;
'Hello world';
myFunc('a', 'b');
myVariable;
true && false;
null;
|
특징: 값이 필요한 곳에 사용 가능
표현식은 JavaScript 코드 중 값이 들어가는 곳이면 어디든 넣을 수 있습니다.
1
2
3
4
5
6
7
8
9
10
| console.log(true && 1 * 5); // 5
// 함수 인자로 사용
myFunc(1 + 2); // 3을 전달
// 삼항 연산자에서 사용
const result = true ? 10 + 5 : 20 - 5;
// 배열 요소로 사용
const arr = [1 + 1, 2 * 3, Math.random()];
|
표현식은 상태를 바꿀 필요가 없음
1
2
3
4
5
6
7
8
| const a = 1; // 이건 Statement (변수 선언문)
// 아래는 모두 Expression (a의 값을 변경하지 않음)
a * 2; // 2
a + 1; // 2
a - 1; // 0
console.log(a); // 1 (변경되지 않음)
|
함수 호출도 표현식
함수 호출은 표현식이지만, 함수 내부에서 상태를 변경하는 문장을 포함할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
| let externalValue = 10;
// 함수 호출은 표현식
const result = changeValue(); // 표현식
function changeValue() {
externalValue = 20; // 이건 Statement (상태 변경)
return 30; // return도 Statement
}
console.log(result); // 30 (반환값)
console.log(externalValue); // 20 (부수 효과)
|
더 나은 접근 - 순수 함수:
1
2
3
4
5
6
| // ✅ 명시적이고 예측 가능한 코드
const getValue = () => {
return 10; // 명시적 반환
};
const result = getValue();
|
또는 매개변수로 전달:
1
2
3
4
5
| const calculate = (n) => {
return n * 2; // 명시적 반환
};
const result = calculate(10); // 20
|
Statement (문장)
정의
문장은 무언가를 수행합니다. Statement는 값이 들어와야 할 곳에 사용할 수 없습니다.
1
2
3
| // ❌ Statement는 값으로 사용 불가
const x = if (true) { 1 }; // Syntax Error
console.log(for (let i = 0; i < 10; i++) {}); // Syntax Error
|
JavaScript의 문장 종류
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 조건문
if (condition) { }
if (condition) { } else { }
// 반복문
while (condition) { }
do { } while (condition);
for (let i = 0; i < 10; i++) { }
for (const key in object) { }
// 제어문
switch (value) { }
break;
continue;
// 변수 선언
let a;
const b = 1;
var c;
// 기타
debugger;
with (object) { } // deprecated (사용 권장하지 않음)
|
함수 선언 vs 함수 표현식
1. 함수 선언 (Function Declaration) - Statement
1
2
3
| function greet(name) {
return `Hello, ${name}`;
}
|
특징:
- 호이스팅됨 (선언 전에 호출 가능)
- 이름이 필수
- Statement이므로 값으로 사용 불가
2. 함수 표현식 (Function Expression) - Expression
익명 함수 표현식
1
2
3
4
5
| const greet = function() {
return "Hello!";
};
console.log(greet()); // "Hello!"
|
네임드 함수 표현식
1
2
3
4
5
| const greet = function myName() {
return "Hello!";
};
console.log(greet.name); // "myName"
|
함수 선언 vs 표현식 판별 규칙
값이 들어올 곳에 함수를 선언하면 표현식, 그렇지 않으면 선언문
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| // 함수 선언
function a() {} // 전역 레벨
if (true) {
function b() {} // 블록 최상위 레벨
}
function outer() {
function inner() {} // 블록 최상위 레벨
}
// 함수 표현식
const func = function() {}; // 값으로 할당
myFunc(function() {}); // 함수 인자
function outer() {
return function inner() {}; // 반환값
}
// ❌ 에러
function() {} // SyntaxError: 함수 선언문은 이름이 필요
|
복잡한 예제
1
2
3
4
5
6
7
8
9
| function a() {
return function b() {
function c() {} // 함수 선언 (블록 최상위)
} // 함수 b는 표현식 (반환값)
}
// a: 함수 선언
// b: 네임드 함수 표현식 (return의 값)
// c: 함수 선언 (함수 b 블록의 최상위)
|
표현식 문장 (Expression Statement)
표현식 뒤에 세미콜론을 붙이면 표현식 문장이 됩니다.
1
2
3
4
5
6
7
8
9
10
11
| // 표현식
1 + 1
// 표현식 문장
1 + 1;
// 표현식으로 사용 가능
console.log(1 + 1); // ✅
// 표현식 문장으로 사용 불가
console.log(1 + 1;); // ❌ Syntax Error
|
예제
1
2
3
4
5
6
7
8
9
10
11
| // 표현식: 값이 필요한 곳에 사용
function add(x) {
return x;
}
add(1 + 1); // ✅ 표현식을 인자로 전달
true ? 1 + 1 : 2 + 2; // ✅ 표현식을 삼항 연산자에 사용
// 표현식 문장: 값이 필요한 곳에 사용 불가
1 + 1; // 표현식 문장 (독립적으로만 사용 가능)
|
세미콜론 vs 콤마 연산자
세미콜론 (;)
여러 줄의 문장을 한 줄에 넣을 수 있습니다.
1
| const a = 1; function b() {}; const c = 2;
|
콤마 연산자 (,)
여러 개의 표현식을 연결하고, 마지막 표현식만 반환합니다.
1
2
3
4
5
| console.log((1 + 2, 3, 4)); // 4
console.log((1, 6 / 3, function() {})); // function() {}
console.log((1, true ? 1 + 1 : 2 + 2)); // 2
|
괄호 필요성:
1
2
3
4
5
| // ✅ 괄호로 묶어서 하나의 값으로 전달
console.log((1, 2, 3)); // 3
// ❌ 괄호 없으면 각각을 인자로 전달
console.log(1, 2, 3); // 1 2 3 (세 개의 인자)
|
함수에서의 콤마 연산자
1
2
3
4
5
| function getLastValue() {
return 1, 2, 3, 4;
}
console.log(getLastValue()); // 4
|
모든 표현식이 왼쪽에서 오른쪽으로 평가되지만, 마지막 값만 반환됩니다.
즉시 실행 함수 표현식: 정의와 동시에 실행되는 함수
기본 형태
1
2
3
4
5
6
7
8
9
10
| // ❌ 함수 선언문은 즉시 실행 불가
function() {} // SyntaxError
// ✅ 괄호로 묶으면 표현식이 됨
(function() {}) // function() {}를 반환
// ✅ 즉시 실행
(function() {
console.log("실행됨!");
})(); // "실행됨!"
|
활용 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // 반환값 받기
const result = (function() {
return 1 + 2;
})();
console.log(result); // 3
// 인자 전달
const greeting = (function(name) {
return `Hello, ${name}!`;
})("Alice");
console.log(greeting); // "Hello, Alice!"
// 로그 출력
console.log((function() {
return "즉시 실행 결과";
})()); // "즉시 실행 결과"
|
IIFE의 활용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // 1. 변수 스코프 격리 (ES6 이전)
(function() {
var privateVar = "외부에서 접근 불가";
console.log(privateVar); // "외부에서 접근 불가"
})();
// console.log(privateVar); // ReferenceError
// 2. 모듈 패턴
const myModule = (function() {
let privateCounter = 0;
return {
increment() {
privateCounter++;
},
getCount() {
return privateCounter;
}
};
})();
myModule.increment();
console.log(myModule.getCount()); // 1
|
💡 참고: ES6에서는 블록 스코프(let, const)와 모듈 시스템이 도입되어 IIFE의 필요성이 줄어들었습니다.
Object Literal vs Block Statement
{}는 문맥에 따라 객체 리터럴 또는 블록 문장이 될 수 있습니다.
Label (레이블)
1
2
3
4
5
6
7
8
9
10
| // 레이블: 반복문 제어에 유용
outerLoop: {
for (let i = 0; i < 2; i++) {
for (let n = 0; n < 2; n++) {
break outerLoop; // 바깥 루프까지 탈출
}
}
}
console.log("루프 종료");
|
블록 문장 (Block Statement)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // 블록 문장: 여러 문장을 그룹화
{
let a = "hello";
console.log(a);
1 + 1;
} // 마지막 표현식 값: 2
// 레이블을 붙인 블록 문장
myLabel: {
let x = 10;
console.log(x);
}
// ❌ 레이블은 변수로 사용 불가
myLabel: function a() {}
console.log(myLabel); // ReferenceError: myLabel is not defined
|
Object Literal vs Block Statement 구분
1
2
3
4
5
6
7
8
9
10
| // Object Literal (객체 리터럴)
console.log({ a: "b" }); // { a: "b" }
const obj = { a: "b" }; // ✅ 값으로 사용
// Block Statement (블록 문장)
{ let a = "b"; func(); 1 + 1 } // 독립적으로만 사용
console.log({ let a = "b" }); // ❌ SyntaxError
const x = { let a = "b" }; // ❌ SyntaxError
|
블록 문장은 값이 아니므로 값이 필요한 곳에 사용할 수 없습니다.
흥미로운 예제
1
2
3
4
| {} + 1 // 1
{1} + 2 // 2
{1 + 1} + 2 // 2
{1 + 1} - 2 // 0
|
이유:
{}는 블록 문장으로 해석됨- 블록 문장은 값을 반환하지 않으므로 암묵적으로
0으로 강제 변환 0 + 1 = 1, 0 + 2 = 2, 0 - 2 = -2… 가 아니라 블록이 무시되고 숫자 연산만 수행
1
2
3
4
5
6
7
8
9
| // 위 코드는 사실상 다음과 같이 해석됨
{} // 빈 블록 (무시됨)
+1 // 단항 플러스 연산자: 1
{1} // 블록 (무시됨)
+2 // 2
{1+1} // 블록 (무시됨)
+2 // 2
|
실전 활용 팁
1. 표현식을 선호하세요
1
2
3
4
5
6
7
8
9
10
| // ❌ Statement 지향적
let result;
if (condition) {
result = "yes";
} else {
result = "no";
}
// ✅ Expression 지향적 (더 간결)
const result = condition ? "yes" : "no";
|
2. 함수형 프로그래밍에서는 표현식 중심
1
2
3
4
5
6
7
8
9
10
| // Statement 사용 (명령형)
const numbers = [1, 2, 3, 4, 5];
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
doubled.push(numbers[i] * 2);
}
// Expression 사용 (함수형, 선언적)
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
|
3. JSX에서는 표현식만 사용 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| // ❌ JSX 안에서 Statement 사용 불가
function MyComponent({ isLoggedIn }) {
return (
<div>
{if (isLoggedIn) { <p>Welcome!</p> }} // SyntaxError
</div>
);
}
// ✅ 표현식(삼항 연산자) 사용
function MyComponent({ isLoggedIn }) {
return (
<div>
{isLoggedIn ? <p>Welcome!</p> : <p>Please login</p>}
</div>
);
}
// ✅ 또는 논리 연산자
function MyComponent({ isLoggedIn }) {
return (
<div>
{isLoggedIn && <p>Welcome!</p>}
</div>
);
}
|
4. 화살표 함수의 간결한 문법
1
2
3
4
5
6
7
8
9
10
11
| // 블록 사용 (Statement) - return 필요
const double = (n) => {
return n * 2;
};
// 표현식 (Expression) - return 불필요
const double = (n) => n * 2;
// 객체 반환 시 괄호로 묶기 (블록과 구분)
const createUser = (name) => ({ name: name }); // ✅
const createUser = (name) => { name: name }; // ❌ undefined 반환
|
마치며
Expression과 Statement의 차이를 이해하는 것은 JavaScript를 제대로 다루는 핵심입니다.
핵심 요약
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| ✅ Expression (표현식)
- 값을 산출
- 값이 필요한 곳 어디든 사용 가능
- 함수 인자, 할당, 연산 등에 사용
✅ Statement (문장)
- 동작을 수행
- 값으로 사용 불가
- if, for, while, switch 등
✅ 함수
- 선언문: 최상위 레벨
- 표현식: 값이 필요한 곳
- IIFE: 즉시 실행 패턴
✅ 실전 팁
- 가능하면 표현식 사용 (더 함수형)
- JSX에서는 표현식만 가능
- 화살표 함수로 간결하게
|
이러한 개념을 명확히 이해하면, 더 간결하고 예측 가능한 JavaScript 코드를 작성할 수 있습니다.
참고 자료