스코프는 다른 언어뿐만 아니라 자바스크립트에서도 중요한 개념이다. 스코프에 대해 알아보자!
스코프(scope)는 사전적 의미로 범위를 뜻한다.
하지만 자바스크립트에서 아래와 같은 의미를 갖는다.
스코프는 식별자를 참조할 수 있는 유요한 범위이다. (식별자는 변수, 함수, 클래스 이름을 뜻한다.)
즉 식별자를 선언한 위치에 따라 유효한 범위가 결정된다.
그렇다면 범위는 어떻게 결정이 될까?
아래 코드처럼 블록 안의 변수는 블록 안에서만 유효하다.
{
const a = "a"
console.log(a) //a
}
만약 블록 밖에서 a를 정의 하면 유효범위 밖에 있기 때문에 에러가 발생한다.
{
const a = "a"
}
console.log(a) //error
자바스크립트의 스코프는 타 언어와 다른 특징을 갖고 있다.
(지역 스코프. 전역 스코프 개념도 있지만 이는 다른 프로그래밍 언어에서 많이 언급되니 생략)
대부분의 언어는 Block-level scope(블록 레벨 스코프) 를 사용한다.
이는 블록 단위로 변수 선언이 유효하다는 뜻이다.
예를 들어보자
c언어의 경우 블록 레벨 스코프이기 때문에 if블록 안에서만 유효하다.
즉 밖에서 x에 접근이 불가하다.
int main(void) {
// block-level scope
if (1) {
int x = 5;
printf("x = %d\n", x);
}
printf("x = %d\n", x); // use of undeclared identifier 'x'
return 0;
}
하지만 자바스크립트는 function-level scope(함수 레벨 스코프) 를 사용한다. 말 그대로 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 외부에서 유효하지 않다는 것이다.
// function-level scope
function foo1() {
if (true) {
var a = 0;
console.log(a); //0
}
console.log(a); //0
}
function foo2() {
if (true) {
let a = 0;
console.log(a); //0
}
console.log(a); //error
}
단, 자바스크립트 ES6부터는 const와 let을 이용해 블록 레벨 스코프도 지원하기 시작했습니다. 따라서 if 문 안에 var 대신 const나 let으로 변수를 선언하면, 다른 언어들처럼 참조하지 못합니다.
요약하면
const와 let은 블록 레벨 스코프 가능
var와 같은 전통적인 자바스크립트의 변수는 함수 레벨 스코프 가능
이름 충돌을 방지하고 블록이 끝나면 메모리에서 제거되기 때문이다.
이러한 스코프 개념으로 자바스크립트에서 가독성과 메모리 절약이 가능하다.
변수는 최대한 필요한 곳에 정의해야 한다.