Skip to Content

5장 표현식과 문

프로그래밍의 기본 구성 요소인 표현식과 문에 대해 학습한다.

이들 개념을 정확히 이해하는 것 = JS뿐 아니라 프로그래밍 전반의 이해도 향상에 필수

5-1. 값의 본질

값(Value): **표현식(Expression)**이 **평가(Evaluate)**되어 생성된 결과물

  • 평가: 표현식을 해석하여 값을 생성하거나 참조하는 과정
  • 즉, 표현식을 계산하여 하나의 값으로 귀결
10 + 20; // '10 + 20'이라는 표현식이 평가되어 숫자 값 30 생성

값의 특성:

  • 변수에 할당되는 것 = 항상
  • 모든 값은 데이터 타입 보유
  • 타입에 따라 다르게 해석됨
  • 프로그램에서 조작 가능한 최소 단위의 데이터
var sum = 10 + 20; // 변수 sum에 할당되는 것은 값 30

5-2. 리터럴

값을 생성하는 방법 중 가장 기본적이고 직관적인 방법 = 리터럴 사용

리터럴(Literal): 사람이 이해할 수 있는 문자 또는 약속된 기호로 값을 표기하는 방법

  • 문자: 숫자, 알파벳, 한글 등
  • 약속된 기호: '', "", [], {}, //
  • JS 엔진에 의해 평가되어 값 생성

리터럴의 평가 과정:

3; // 숫자 리터럴

JS 엔진이 주어진 리터럴을 평가해서 메모리에 저장되는 값을 생성한다.

  1. 개발자가 숫자 리터럴 3 작성
  2. JS 엔진이 런타임에 리터럴 평가
  3. 숫자 값 3 생성 → 메모리에 저장

다양한 리터럴:

a2.png

리터럴 종류예시생성되는 값
정수 리터럴100정수 100
부동소수점 리터럴10.5실수 10.5
2진수 리터럴0b01000001정수 65
8진수 리터럴0o101정수 65
16진수 리터럴0x41정수 65
문자열 리터럴'Hello', "World"문자열
불리언 리터럴true, false불리언 값
null 리터럴nullnull
undefined 리터럴undefinedundefined
객체 리터럴{ name: 'Lee' }객체
배열 리터럴[1, 2, 3]배열
함수 리터럴function() {}함수 객체
정규 표현식 리터럴/ab+c/정규 표현식

5-3. 표현식

표현식(Expression): 값으로 평가될 수 있는 문(statement)

var score = 100; // 100은 표현식

표현식의 구성:

다음 요소들의 조합으로 구성 가능:

  • 리터럴
  • 식별자 (변수, 함수 등)
  • 연산자
  • 함수 호출

핵심:

  • 표현식 평가 → 새 값 생성 or 기존 값 참조
  • 리터럴도 값으로 평가됨 → 리터럴 = 표현식
  • 값이 위치할 수 있는 곳 = 표현식도 위치 가능

다양한 표현식:

// 리터럴 표현식 10 'Hello' // 식별자 표현식 (선언 존재 가정) sum person.name arr[1] // 연산자 표현식 10 + 20 sum = 10 sum !== 10 // 함수/메서드 호출 표현식 square() person.getName()

표현식과 값의 동치성:

모든 표현식은 값으로 평가 → 표현식과 값은 동치(Equivalent)

var x = 1 + 2; // 1 + 2는 표현식, 3이라는 값으로 평가 // 표현식 1 + 2와 값 3은 동치 → 다음과 같이 표현 가능: var x = 3;

5-4. 문

문(Statement): 프로그램을 구성하는 기본 단위이자 최소 실행 단위

문의 역할 = 명령 수행

→ 프로그램 = 문들의 집합

→ 프로그래밍 = 문을 작성하고 순서에 맞게 나열하는 것

5-4-1. 문의 구성: 토큰

문은 여러 **토큰(Token)**으로 구성

토큰: 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소

a3.png

토큰의 종류:

  • 키워드: var, let, const, if, for
  • 식별자: 변수명, 함수명 등
  • 연산자: +, -, =, ===
  • 리터럴: 숫자, 문자열 등
  • 특수 기호: ;, ., ,

예제:

var sum = 1 + 2;

위 문의 토큰 분해:

  • var (키워드)
  • sum (식별자)
  • = (할당 연산자)
  • 1 (숫자 리터럴)
  • + (산술 연산자)
  • 2 (숫자 리터럴)
  • ; (세미콜론)

5-4-2. 문의 분류

1. 선언문 (Declaration Statement)

변수나 함수 선언

var x; // 변수 선언문 function foo() {} // 함수 선언문

2. 할당문 (Assignment Statement)

값 할당

x = 5;

3. 조건문 (Conditional Statement)

조건에 따라 코드 블록 실행 결정

if (x > 1) { console.log(x); }

4. 반복문 (Loop Statement)

특정 코드 블록 반복 실행

for (var i = 0; i < 2; i++) { console.log(i); }

5. 기타

console.log('Hello'); // 함수 호출문 break; // break 문 continue; // continue 문 return x; // return 문

5-5. 세미콜론과 세미콜론 자동 삽입

세미콜론(;): 문의 종료 표시

JS 엔진은 세미콜론을 기준으로 문의 종료 위치 파악 → 순차적으로 실행

세미콜론 사용 원칙:

var x = 5; // 세미콜론으로 문 종료 var y = 10;

주의: 코드 블록의 경우

중괄호 {}로 묶인 코드 블록(블록문) 뒤 → 세미콜론 불필요

if (x > 0) { console.log(x); } // 세미콜론 불필요 function foo() { return x; } // 세미콜론 불필요 for (var i = 0; i < 10; i++) { console.log(i); } // 세미콜론 불필요

이유: 코드 블록은 자체 종결성(Self Closing) 보유

→ 블록의 끝 = 문의 종료

5-5-1. 세미콜론 자동 삽입 기능

ASI(Automatic Semicolon Insertion): JS 엔진이 문의 끝 예측 지점에 자동으로 세미콜론 삽입

var x = 5 var y = 10 console.log(x + y) // ASI에 의해 다음과 같이 해석: // var x = 5; // var y = 10; // console.log(x + y);

세미콜론 사용 논쟁:

  • 찬성: 명시적 표현으로 의도 명확화 + ASI 예측 불가 동작 방지
  • 반대: ASI 신뢰 + 코드 간결성 유지

⇒ 하지만 ASI가 항상 개발자 의도대로 동작한다는 보장 없음

세미콜론 명시적 사용 권장

ASI의 예측 불가 동작:

function foo() { return { bar: 'baz' } } console.log(foo()); // undefined (의도: 객체 반환) // ASI가 다음과 같이 해석: // return; // { bar: 'baz' }

5-6. 표현식인 문과 표현식이 아닌 문

문과 표현식의 구분 기준 = 변수에 할당 가능한가

표현식인 문 (Expression Statement)

값으로 평가됨 → 변수에 할당 가능

var x; x = 1 + 2; // 할당문은 표현식이면서 문 var result = (x = 100); // 할당문 결과를 변수에 할당 가능

표현식이 아닌 문 (Non-Expression Statement)

값으로 평가 안 됨 → 변수에 할당 불가능

var foo = var x; // SyntaxError: Unexpected token var // 변수 선언문은 값으로 평가되지 않음 → 표현식이 아님

5-6-1. 크롬 개발자 도구에서의 완료 값

크롬 콘솔에서 문 실행 → 완료 값(Completion Value) 출력

var x = 10; // 콘솔 출력: undefined (표현식 아닌 문)

표현식 아닌 문 → 완료 값은 언제나 undefined

→ 완료 값은 값이 아니므로 변수에 할당/참조 불가

x = 100; // 콘솔 출력: 100 (표현식인 문)

표현식인 문 → 평가된 값을 완료 값으로 보유

5-6-2. 구분 방법 정리

표현식이 아닌 문:

var x; // 선언문 if (x > 0) { } // 조건문 for (var i = 0; i < 5; i++) { } // 반복문

표현식인 문:

1; // 리터럴 표현식 1 + 2; // 연산자 표현식 x = 1 + 2; // 할당 표현식 foo(); // 함수 호출 표현식

검증 방법: 변수에 할당 시도

// 표현식인 문 → 할당 가능 var result1 = 1 + 2; // 가능 var result2 = x = 100; // 가능 var result3 = foo(); // 가능 // 표현식 아닌 문 → 할당 불가 var result4 = var y; // SyntaxError var result5 = if (true) { }; // SyntaxError

학습 점검 문제

문제 1: 표현식 구분하기

다음 중 표현식이 아닌 것을 모두 고르시오.

A. 100 B. var total; C. total = 50 + 50; D. function add() {} E. 10 > 5 F. for (var i = 0; i < 10; i++) {}

해답 보기

정답: B, D, F

  • A (표현식): 숫자 리터럴, 100으로 평가됨
  • B (표현식 아님): 변수 선언문, 값으로 평가되지 않음
  • C (표현식): 할당문, 할당된 값으로 평가됨
  • D (표현식 아님): 함수 선언문 (단, 함수 표현식은 표현식임)
  • E (표현식): 비교 연산자 표현식, true 또는 false로 평가됨
  • F (표현식 아님): 반복문, 값으로 평가되지 않음

문제 2: 리터럴의 이해

다음 코드의 실행 결과를 예측하시오.

var a = 10; var b = 10.0; var c = 0b1010; var d = 0o12; var e = 0xA; console.log(a === b); console.log(a === c); console.log(c === d); console.log(d === e);

해답 보기

실행 결과: 모두 true

이유:

  • 자바스크립트는 정수와 실수를 구분하지 않고 모두 실수로 처리
  • 다양한 진법의 숫자 리터럴은 모두 10진수로 해석됨
  • 2진수 0b1010, 8진수 0o12, 16진수 0xA는 모두 10진수 10과 같음

문제 3: 표현식과 문의 구분

다음 코드에서 에러가 발생하는 라인을 찾고 이유를 설명하시오.

var x = 10; // 1번 줄 var y = x = 20; // 2번 줄 var z = var w = 30; // 3번 줄 var result = (x > y); // 4번 줄

해답 보기

에러 발생 라인: 3번 줄

이유:

  • var w = 30은 변수 선언문으로, 표현식이 아닌 문
  • 표현식이 아닌 문은 값으로 평가되지 않으므로 변수에 할당 불가능
  • 1번: 정상 (리터럴 표현식 10을 할당)
  • 2번: 정상 (할당문 x = 20은 표현식이므로 할당 가능, 결과값 20)
  • 3번: 에러 (선언문은 표현식이 아님)
  • 4번: 정상 (비교 표현식 결과인 boolean 값을 할당)

문제 4: 세미콜론 자동 삽입

다음 코드의 실행 결과를 예측하고, ASI가 어떻게 동작했는지 설명하시오.

function getValue() { return { value: 42 } } console.log(getValue());

해답 보기

실행 결과: undefined

ASI의 동작: ASI가 return 다음에 자동으로 세미콜론을 삽입하여 다음과 같이 해석:

function getValue() { return; // undefined 반환 { // 도달할 수 없는 코드 value: 42 } }

올바른 작성법:

function getValue() { return { value: 42 }; } // 또는 function getValue() { return { value: 42 }; }

문제 5: 실무 시나리오

다음 상황에서 각각 표현식과 문을 사용하여 코드를 작성하시오.

상황 1: 사용자의 나이를 변수에 저장하고, 20세 이상인지 확인하여 결과를 다른 변수에 저장

상황 2: 배열의 모든 요소를 2배로 만드는 코드 작성 (map 사용)

해답 보기

상황 1:

var age = 25; // 선언문과 할당문 var isAdult = age >= 20; // 표현식 (비교 연산)의 결과를 변수에 할당 console.log(isAdult); // true

상황 2:

var numbers = [1, 2, 3, 4, 5]; var doubled = numbers.map(function(num) { return num * 2; // 표현식: num * 2 }); console.log(doubled); // [2, 4, 6, 8, 10] // 또는 화살표 함수 사용 var doubled = numbers.map(num => num * 2); // 더 간결한 표현식

심화 학습: 표현식의 평가 순서

복잡한 표현식이 평가될 때는 연산자 우선순위결합성에 따라 순서가 결정된다.

연산자 우선순위 예시:

var result = 10 + 5 * 2; // 20 (곱셈이 덧셈보다 우선)

평가 순서:

  1. 5 * 2 → 10
  2. 10 + 10 → 20

괄호를 사용한 명시적 우선순위 지정:

var result = (10 + 5) * 2; // 30 (괄호 안이 먼저 평가)

평가 순서:

  1. (10 + 5) → 15
  2. 15 * 2 → 30

결합성 예시:

var x = 1; x = x + 1; // 우변의 표현식이 먼저 평가된 후 좌변에 할당

평가 순서:

  1. 우변 x + 1 평가 → 2
  2. 좌변 x에 2 할당

심화 학습: 부수 효과가 있는 표현식

대부분의 표현식은 값을 생성할 뿐 다른 영향을 주지 않지만, 일부 표현식은 **부수 효과(Side Effect)**를 가진다.

할당 표현식:

var x = 1; x = 10; // x의 값을 변경하는 부수 효과

증감 연산자:

var x = 5; x++; // x의 값을 6으로 변경 (부수 효과), 표현식의 값은 5 ++x; // x의 값을 7로 변경 (부수 효과), 표현식의 값은 7

함수 호출:

var arr = [1, 2, 3]; arr.push(4); // 배열을 변경하는 부수 효과

부수 효과를 가진 표현식은 프로그램의 상태를 변경하므로, 사용 시 주의가 필요하다. 함수형 프로그래밍에서는 부수 효과를 최소화하여 코드의 예측 가능성을 높이는 것을 지향한다.

Last updated on