[Javascript] 스코프(Scope)
목차
1. 스코프 (Scope)
① 전역 스코프와 지역 스코프 (Global Scope & Local Scope)
② 함수 스코프와 블록 스코프 (Function Scope & Block Scope)
2. 참고한 문헌
1. 스코프 (Scope)
이번 게시글에서 다루는 내용은 이전 게시글인 '[Javascript] 함수'에서 이어지는 내용이기 때문에
Javascript의 함수에 대해서 잘 모른다면 아래 링크로 들어갔을 때 나오는 게시물을 참고하길 바란다.
[Javascript] 함수
scope, 해당 단어를 직역하면 '범위'라는 의미를 가진다.
프로그래밍에서의 스코프(Scope)란 '변수 혹은 함수를 선언했을 때 갖게 되는 유효 범위'를 말한다.
Javascript에서의 스코프는 크게 전역 스코프 (Global Scope)와 지역 스코프 (Local Scope)로 나눌 수 있으며
추가적으로 지역 스코프는 함수 스코프 (Function Scope), 블록 스코프 (Block Scope)로 나눌 수 있다.
① 전역 스코프와 지역 스코프 (Global Scope & Local Scope)
제일 먼저 전역 스코프와 지역 스코프에 대해 정의하자면 다음과 같이 정의할 수 있다.
전역 스코프 (Global Scope)
=> 어느 위치에서든지 해당 변수로 접근할 수 있는 것을 말한다.
지역 스코프 (Local Scope)
=> 변수를 선언한 위치 (함수나 블록 내부)에서만 해당 변수로 접근할 수 있고
외부에서는 해당 변수로 접근할 수 없는 것을 말한다.
이해를 돕기 위해서 예제를 하나 준비해 놨다.
아래 예제를 한 번 실행해 보자.
//전역 스코프와 지역 스코프
let A = 10;
function func(){
let B = "Hi";
A = 20;
console.log(B);
}
func();
console.log(A);
console.log(B); //error
프로그램 실행 과정
(1). 변수 A 선언, 값을 숫자 10으로 초기화
(2). 함수 func() 선언, 함수 내부에는 변수 B와 변수 A의 값을 20으로 변경, 변수 B의 값을 출력하는 코드가 존재한다.
(3). 함수 func()를 실행하고 나서, 변수 A의 값을 console에 출력해 보면 20이라는 값이 출력된다.
(4). 이후, func() 함수 내부에서 선언한 변수 B의 값을 출력하려고 하면 Reference Error가 발생하는 것을 확인할 수 있다.
여기서 변수 A는 전역 스코프를 가진 전역 변수로, func() 함수에서 변수 A의 값을 변경하고 (10 → 20)
이후에 변수 A의 값을 console에 출력했을 때 변경한 값인 숫자 20이 출력되는 것을 통해서 확인할 수 있다.
그리고 변수 B는 함수 func() 내부에서 선언한 지역 변수로 지역 스코프 (함수 스코프)를 가진 것을
func() 함수 외부에서 해당 변수로 접근하려고 했을 때 error가 발생하는 것을 통해서 확인할 수 있다.
② 함수 스코프와 블록 스코프 (Function Scope & Block Scope)
함수 스코프 (Function Scope)
=> 함수 내부에서 선언한 변수는 해당 함수 내부에서만 접근할 수 있고, 외부에서는 접근할 수 없는 것을 말한다.
//함수 스코프
function func(){
let B = "Hi";
console.log(B);
}
func();
console.log(B); //error
위의 예제에서 함수 func() 내부에서 선언한 변수 B는 함수 스코프를 가진 지역 변수로해당 변수를 선언한 함수 func() 외부에서 접근할 수 없는 것을 예제 실행 결과를 통해서 확인할 수 있다.(함수 스코프는 지역 스코프에 포함된 개념이다.)
블록 스코프 (Block Scope)
=> 변수를 선언한 블록 내부에서만 해당 변수로 접근할 수 있고, 블록 외부에서는 해당 변수로 접근할 수 없는 것
여기서 '블록'은 function을 제외한 if, while, for 등의 '{ }' (중괄호)로 둘러싸인 부분을 말한다.
(function은 함수 스코프를 가지고 있기 때문에 제외한다.)
//블록 스코프
//구구단 2단 출력 (1부터 6까지)
let num = 2;
for (let dan = 1; dan <= 6; dan++){
let ans = num * dan;
console.log(`${num} * ${dan} = ${ans}`);
}
console.log(ans); //Error
프로그램 실행 과정
(1). 변수 num 선언, 값을 숫자 2로 초기화
(2). for 반복문을 통해 구구단 2단을 1부터 6까지 출력한다.
(변수 num과 dan의 곱 연산 결과를 변수 ans에 저장한다.)
(3). for 반복문 외부에서 변수 ans로 접근 시도, Reference Error가 발생한다.
(ans is not defined, 'ans'라는 변수가 정의되지 않았다.)
Error가 발생한 부분은 'console.log(ans);'이다. 여기서 변수 ans는 for 문 내부에서 선언한 변수로
해당 변수는 블록 스코프를 가지고 있기 때문에 for 문 블록 외부에서는 해당 변수로 접근하는 것은 불가능하다.
그렇기 때문에 해당 코드를 실행하면 변수 ans의 값을 출력해야 하지만
해당 변수는 블록 스코프를 가진 지역 변수로 외부에서 접근할 수 없기 때문에
Reference Error가 발생하고 'ans is not defined' (변수 ans가 정의되지 않았습니다.)라는 메시지를 출력하게 된다.
물론 완전히 접근이 불가능한 것은 아니다.
변수 ans를 선언했을 때 사용한 키워드를 let에서 var로 바꾸면
외부에서 접근하는 것이 가능해진다.
//블록 스코프
//구구단 2단 출력 (1 ~ 6 까지)
let num = 2;
for(let dan = 1; dan <= 6; dan++){
//let ans = num * dan;
var ans = num * dan;
//변수 선언 키워드를 let에서
//var로 변경
console.log(`${num} * ${dan} = ${ans}`);
}
console.log(ans);
//마지막에 저장된 값인 12가 출력된다.
변수 선언 키워드를 let에서 var로 변경했을 때
해당 변수 ans를 선언한 블록 외부에서도 접근할 수 있는 것을 위의 예제 실행 결과를 통해서 확인할 수 있다.
그렇다면 왜 이러한 결과가 나오게 된 것일까?
그 이유에 대해서는 다음 장에서 다루도록 하겠다.
2. 참고한 문헌
웹 프론트엔드를 위한 자바스크립트 첫 걸음 (인프런)