미누에요

[JavaScript] var, let, const 키워드, 함수 레벨 스코프(Function-level scope), 블록 레벨 스코프(Block-level scope) 본문

JavaScript

[JavaScript] var, let, const 키워드, 함수 레벨 스코프(Function-level scope), 블록 레벨 스코프(Block-level scope)

미누라니까요 2025. 1. 23. 17:43
728x90
반응형
SMALL

JavaScript를 조금이라도 공부해본 사람이라면 var 키워드를 되도록 사용하지 말아야 한다고 들어보았을 것이다.

하지만 자세한 이유는 아마 나중에 깊게 배운다는 식으로 넘어갔을 가능성이 높다.

오늘은 var 키워드와 나머지 let, const 키워드에 대해 설명해보고자 한다.

 

var 키워드

  • 변수 중복 선언 가능
  • 함수 레벨 스코프(Function-level scope)

var 키워드로 선언한 변수는 함수 레벨 스코프(Function-level scope)를 가진다.

함수 레벨 스코프란 함수의 코드 블록만을 지역 스코프로 인정한다는 말이다. 

var x = 1;

if(true){
	var x = 100;
}

console.log(x); // 100

 

위 코드에서 if문 내부에서 var 키워드로 변수를 한번 더 선언하고 있다. 

var 키워드는 중복 선언이 가능하기 때문에 같은 변수를 두 번 선언하는 것은 문제가 없지만, 원래 일반적으로 예상하기에 마지막의 출력이 전역 스코프에 존재하는 x를 따라가기 때문에 1이라고 생각할 수 있다.

 

하지만 위에서 var 키워드는 함수 레벨 스코프(Function-level scope)라고 했다.

즉, if문은 함수가 아니기 때문에 if문 내부에 있는 var x = 100;은 사실상 전역 스코프에 선언한 것이나 다름이 없는 것이다.

 

따라서 마지막 출력은 100이 나오게 된다.

 

 

이러한 성질 때문에 var 키워드는 너무 지나치게 많은 전역 변수의 사용을 초래할 수 있다. 따라서 var 키워드의 사용은 되도록 지양해야한다.

 

 

let 키워드

  • 변수 중복 선언 불가능
  • 블록 레벨 스코프(block-level scope)

var 키워드의 단점을 보완하기 위해 ES6에서 도입된 키워드가 let 키워드이다.

간단하게 말하자면 우리가 원래 알고 있던 변수와 같다고 생각하면 좋을 거 같다.

let f = 1;

if(true){
	let f = 2;
        let h = 9;
}

console.log(f); // 1
console.log(h); // ReferenceError : h is not found

 

위 코드는 let을 사용한 코드이다.

블록 레벨 스코프는 블록 단위로 스코프를 나눈다는 말이다. 즉, 함수, if문 등 {}로 이루어진 문에 대해 지역 스코프를 가진다는 말이다.

 

그렇기 때문에 위 코드의 if문 안의 변수는 모두 지역 스코프를 갖는다.

따라서 마지막 출력 부분에는 전역 변수 f의 값이 출력되고, 전역 변수 중 h는 존재하지 않으므로 에러가 발생하게 된다.

 

 

 

const 키워드

  • 변수 중복 선언 불가능
  • 블록 레벨 스코프(block-level scope)
  • 선언과 동시에 초기화
  • 값 재할당 불가능

const 키워드는 흔히 상수를 표현할 때 사용한다.

그리고 선언과 동시에 값을 할당해야하고, 재할당이 불가능하다는 점이 특징이다.

 

기본적인 프로그래밍 언어들과 동일하므로 간략하게 설명하겠다.

 

 

 

변수 호이스팅에서의 var, let의 차이

변수 호이스팅은 변수, 함수 선언이 코드 실행 전에 스코프의 최상단으로 끌어올려지는 것처럼 동작하는 특징을 말한다.

 

console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1;
console.log(foo); // 1

 

위 코드에서 우리는 foo를 선언하기 이전에도 console.log를 통해 사용이 가능하다. (undefined가 뜨지만 값에 접근은 가능하다)

이러한 현상이 발생하는 이유는 호이스팅인데, var 키워드를 사용하면 런타임 이전에 모든 변수와 함수 선언을 수행한다. 

코드가 실행된 이후에는 값을 할당하여 사용하는 작업만 수행되기 때문에, 이미 빈 값으로 선언된 상태인 foo에 접근할 수 있는 것이다.

 

var 키워드로 선언한 변수는 런타임 이전에 선언 단계와 초기화 단계가 진행된다. 

따라서 코드가 실행될 때 값이 할당되지 않아도 변수에 접근이 가능하다.(undefined가 뜰 뿐..)

 

하지만 let 키워드로 선언하게 된다면 런타임 이전에 선언 단계만 수행된다.

그 이후에 코드가 실행되면서 초기화 단계를 거치기 때문에 값을 할당하기 전에는 값에 접근할 경우 ReferenceError가 발생한다.

 

 

이러한 차이점이 존재하기 때문에 ES6 부터는 let을 사용하여 변수의 값을 추적하기 쉬워졌고, var 키워드를 사용하면 여기저기서 호이스팅되어 어떤 값이 올 지 예측이 어려워 코드의 복잡성을 높이기 때문에 잘 사용하지 않는 것이다.

728x90
반응형
LIST