Table Of Contents
자바스크립트의 변수와 함수는 생성과 동시에 자신에게 접근하거나 호출할 때 일정한 제약 범위를 갖는데, 이를 스코프(Scope)라고 합니다. 스코프는 쉽게 말해 변수나 함수에 접근하거나 호출할 수 있는 범위를 말합니다.
전역, 지역 스코프
변수가 전역 스코프를 갖는다는 것은 해당 변수를 코드 어디에서나 접근할 수 있다는 의미입니다. 반면 변수가 지역 스코프를 갖는다는 것은 특정 영역에서만 해당 변수에 접근할 수 있다는 의미입니다. 어떤 경우에 변수나 함수가 전역 또는 지역스코프를 갖는지 예제를 보면서 알아보겠습니다.
다음은 함수 외부에 선언한 변수를 함수 내부에서 접근하는 예입니다.
코드를 불러오는 중 입니다 ...① 함수 외부에 변수 a를 선언하고 1로 초기화했습니다. ② 함수 foo를 호출합니다. 함수 foo가 실행되어 변수 a를 콘솔에 출력합니다. ③ 함수 bar를 호출합니다. 함수 bar가 실행되어 변수 a를 콘솔에 출력합니다. ④ ①에서 선언한 변수 a를 콘솔에 출력합니다.
변수 a는 조건문이나 반복문 또는 함수의 중괄호 내부에서 선언하지 않았습니다. 이 경우 변수 a는 전역 스코프를 갖습니다. 따라서 코드 어디에서나 이 변수에 접근할 수 있습니다. 이렇듯 전역 스코프를 갖는 변수를 ‘전역 변수(Global Variable)’라고 합니다.
다음은 함수 내부에 변수를 선언하고, 함수 외부에서 그 변수에 접근하는 예입니다.
코드를 불러오는 중 입니다 ...① 변수 a를 함수 foo 내부에 선언하였습니다. ② 함수 foo 외부에서 변수 a에 접근합니다. 이 코드를 실행하면 오류가 발생합니다. 변수 a에 접근 할 수 없기 때문입니다.
변수 a는 함수 내부에 선언되었습니다. 이 경우 변수 a는 지역 스코프를 갖습니다. 따라서 변수를 선언한 함수 내부에서만 접근할 수 있습니다. 이렇듯 지역 스코프를 갖는 변수를 ‘지역 변수(Local variable)’라고 합니다. 자바스크립트의 변수는 선언한 위치에 따라 자신에게 접근할 수 있는 범위가 결정되는데, 이를 ‘변수의 스코프’라고 합니다.
변수를 함수 내부에 선언했을 때만 지역 스코프를 갖는 것은 아닙니다. 조건문이나 반복문과 같이 블록 내부에서 선언 해도 변수는 지역 스코프를 갖습니다. 다음은 조건문 내부에 변수를 선언하고 해당 변수를 조건문 외부에서 접근하는 예입니다.
코드를 불러오는 중 입니다 ...① 조건문 내부에서 변수 a를 선언합니다. ② 조건문 외부에서 변수 a에 접근합니다. 이 코드를 실행하면 오류가 발생합니다. 변수 a는 조건문 내부에서 선언했기 때문에 지역 스코프를 갖습니다.
다음은 반복문 내부에 변수를 선언하고 해당 변수를 반복문 외부에서 접근하는 예입니다.
코드를 불러오는 중 입니다 ...① 반복문 내부에서 변수 a를 선언합니다. ② 반복문 외부에서 변수 a에 접근합니다. ③ 반복문 외부에서 반복문의 카운터 변수 i에 접근합니다.
이 코드를 실행하면 오류가 발생합니다. 변수 a는 반복문 내부에서 선언되어 지역스코프를 갖기 때문입니다. 또한 반복문의 카운터 변수 i 또한 반복문 내부에서 선언한 변수와 동일하게 지역 스코프를 갖습니다. 따라서 변수 a와 i는 반복문 외부에서 접근할 수 없습니다.
변수가 아닌 함수도 스코프를 갖습니다. 다음은 함수가 또 다른 함수를 호출하는 예입니다.
코드를 불러오는 중 입니다 ...두 개의 함수 foo와 bar를 선언한 다음, 함수 bar를 호출합니다. 그리고 함수 bar에서는 다시 함수 foo를 호출합니다. 이때 함수 foo는 조건문이나 반복문 또는 다른 함수 내부에서 선언하지 않았기 때문에 전역 스코프를 갖습니다. 따라서 코드 어디에서나 호출할 수 있습니다.
다음은 함수 내부에 중첩 함수를 만들고 함수 외부에서 이 중첩 함수를 호출하는 예입니다.
코드를 불러오는 중 입니다 ...① 함수 foo 내부에서 중첩 함수 bar를 선언합니다. ② 함수 bar를 호출합니다.
이 코드는 실행하면 오류가 발생합니다. 함수 bar는 함수 foo 내부에 선언한 중첩함수입니다. 이렇듯 함수 내부에서 선언한 함수 bar는 지역 스코프를 갖습니다. 따라서 함수 foo 외부에서 호출할 수 없습니다.
조건문이나 반복문 내부에 선언한 함수도 지역 스코프를 갖습니다.
다음은 조건문 내부에 함수를 선언하고 해당 함수를 조건문 외부에서 호출하는 예입니다.
코드를 불러오는 중 입니다 ...이 코드를 실행하면 오류가 발생합니다. 함수 foo는 조건문 내부에서 선언되었습니다. 따라서 이 함수는 지역 스코프를 가지며 조건문 외부에서 호출할 수 없습니다.
다음은 반복문 내부에 함수를 선언하고 해당 함수를 반복문 외부에서 호출하는 예입니다.
코드를 불러오는 중 입니다 ...이 코드를 실행하면 오류가 발생합니다. 함수 bar를 반복문 내부에 선언했습니다. 따라서 이 함수 역시 지역 스코프를 가지며 반복문 외부에서 호출할 수 없습니다.
블록, 함수 스코프
자바스크립트의 변수나 함수는 중괄호로 둘러싸인 부분을 뜻하는 ‘블록(block)’을 기준으로 지역 스코프가 결정됩니다. 블록 기준으로 지역 스코프를 정한다고 해서 ‘블록 스코프(block scope)’라고 합니다.
대다수 언어는 변수를 선언한 블록에 따라 지역 스코프가 정해집니다. 그러나 자바스크립트의 지역 스코프는 블록 스코프 외에도 한 가지 더 있습니다. 바로 함수를 기준으로 지역 스코프를 정하는 ‘함수 스코프’입니다.
블록 스코프
(Block Scope) | 함수 스코프
(Function Scope) |
블록 내부에서 선언한 변수가 갖는 스코프 | 함수 내부에서 선언한 변수가 갖는 스코프 |
var 키워드로 선언한 변수는 블록 스코프를 갖는 let이나 const 키워드와 달리 함수 스코프를 갖습니다. 다음은 조건문 내부에서 var로 변수를 선언한 예입니다.
코드를 불러오는 중 입니다 ...var로 선언한 변수 a는 조건문 내부에서 선언했으나 조건문 외부에서 접근할 수 있습니다. 이는 var로 선언한 변수가 블록 스코프가 아닌 함수 스코프를 갖기 때문입니다. 함수 스코프를 갖는다는 것은 함수 내부에서 선언한 변수만 지역 스코프를 갖는다는 의미입니다. 따라서 함수가 아닌 조건문의 블록 내부에서 선언한 변수 a는 전역 스코프를 갖습니다.
다음은 함수 내부에서 var로 변수를 선언한 예입니다.
코드를 불러오는 중 입니다 ...var로 선언한 변수 a는 함수 foo 내부에서 선언했기 때문에 함수 스코프를 갖습니다. 따라서 외부에서 a에 접근하려면 오류가 발생합니다.
var는 대다수 프로그래밍 언어에서는 잘 쓰지 않는 ‘함수 스코프’를 갖고 있습니다. 앞서 var를 사용하면 변수의 이름을 중복해 사용해도 아무런 문제가 발생하지 않았습니다. 이렇듯 var는 프로그래머를 혼란에 빠뜨릴 여지가 많습니다. 따라서 보다 보편적인 let이나 const 키워드를 이용해 변수를 선언하기를 권합니다. 이 책도 var 키워드를 사용하지 않습니다.