const variablesArea = function () {
let confined = "I'm trapped!";
}
console.log(confined); // confined is not defined ...
JavaScript에서 함수에 선언한 값이 외부에서 호출되지 않는다. 이것은 Scope라는 개념이 있어서 그렇다.
우선 전역 스코프와 지역 스코프에 대해서 먼저 알아보자 .
전역 스코프, 지역 스코프
let x = 0;
const scopeTest = function () {
let y = 1;
console.log(x); // 0
}
console.log(x); // 0
console.log(y); // y is not defined ...
위 코드의 전체 영역을 전역 스코프 공간이라고 한다.
그리고 function 안 코드를 지역 스코프 공간이라고 한다.
이때 변수 x는 scopeTest라는 함수의 지역 스코프 안에서 참조가 가능할까?
전역 스코프의 변수 x는 지역 스코프에서 참조할 수 있다.
전역 스코프에 존재하는 변수는 지역 스코프 내에서 참조될 수 있다. 이렇게 전역 스코프에서 존재하는 변수를
전역 변수라고 한다. 그렇다면 지역 스코프 내에 존재하는 변수 y는 전역 스코프에서 참조될 수 있을까?
지역 스코프의 변수 y는 전역 스코프에서 참조할 수 없다.
지역 스코프 내에서 선언된 변수는 해당 지역에서만 존재할 수 있다. y와 같이 특정 지역 스코프 내에서 존재하는
변수를 지역 변수라고 이야기한다.
이제 지역 스코프를 생성하는 몇가지 종류에 대해서 알아보자,
함수 스코프
JavaScript에서 지역 스코프를 생성하는 종류는 함수 레벨 스코프와 블록 레벨 스코프가 있다.
우선, 함수 스코프란 함수를 실행할 때 생겨나는 지역 스코프이다.
대부분의 프로그래밍 언어는 블록 레벨 스코프를 따른다. 하지만 과거 JavaScript는 함수 레벨 스코프를 따른다.
현재 let, const 키워드의 등장으로 블록 스코프를 따를 수 있게 되었지만,
let x = 0;
const scopeTest = function () {
let y = 1;
console.log(x);
}
console.log(y);
scopeTest 함수가 바로 함수 스코프에 의해 생성된 지역 스코프이다. 함수에 의해 생성된 스코프이므로 y라는 변수는
해당 지역 스코프 내에만 존재하는 것이다. 자바스크립트는 이전에 함수 레벨 스코프만 따랐다고 이야기 했는데,
그 이유가 바로 var 키워드 때문이다.
JavaScript는 최초에는 var라는 키워드만 존재 했고, var는 함수 스코프를 따르는 키워드이다.
함수가 실행되는 경우에만 해당 지역 스코프가 생성되었다.
if(...) {
var x = 0;
}
console.log(x); // 0
var 키워드는 함수 스코프만 따르기 때문에 if 문으로 인해 만들어진 블록 스코프를 따르지 않았고, 지역 스코프에
갇히지 않는 변수가 다수 생성되었고, 전역 스코프로 해당 변수가 들어가게 되었다. 때문에 전역 변수의 선언을
남발하게 되며 불필요하게 과도한 메모리를 소모하는 문제가 발생했다.
이러한 문제를 해결하기 위해 블록 스코프를 따르는 let 키워드와 const 키워드가 등장하게 되었다.
블록 스코프
함수 스코프는 함수를 실행할 때 생성되는 스코프였다면, 블록 스코프는 코드 블록에 의해 생성되는 스코프이다.
if문, for문, while문 등 중괄호를 사용해 코드 블록을 작성하는 환경에서 생성된다.
for (let i = 0; i < 6; i ++) {
let a = "123";
if (i > 3) {
let a = "asd";
console.log(a); // "asd"
}
console.log(a); // "123"
}
위 코드는 두개의 블록 스코프가 존재한다. for문과 내부의 if문이다.
두 개의 블록 스코프는 서로 다른 영역으로 각각의 스코프에서 생성되는 변수는 서로 영향을 주지 않는다.
let 키워드와 const 키워드는 블록 스코프를 따르키 때문이 이러한 동작이 가능하다. 또한 함수 역시 코드 블록이 생기기
때문에 영향을 받는다.
let a = "123";
if (i > 3) {
console.log(a); // "123"
}
console.log(a); // "123"
for문의 블록 스코프와 if문의 블록 스코프는 다르다고 했는데 if문 안에 있는 console.log는 왜 에러가 발생하지 않을까?
if문에 의해 생성된 블록 스코프 내에 a라는 변수는 존재하지 않는데 for 블록 스코프에 존재하는 a변수를 참조한다.
이 이유는 스코프 체이닝 때문이다.
자바스크립트는 변수를 참조하는 코드를 만나게 됐을 때, 현재 블록 스코프 내에서 변수를 참조하고자 한다.
이때 현재 블록 스코프 내에 해당 변수가 존재하지 않는 경우, 상위 스코프로 올라가 다시 탐색을 진행한다.
이러한 과정을 스코프 체이닝이라고 하며, if문에서의 console.log(a)가 에러를 발생시키지 않는 이유이다.
'JavaScript' 카테고리의 다른 글
Object (1) | 2024.09.21 |
---|---|
호이스팅 (1) | 2024.08.21 |
JavaScript defer & async (2) | 2024.06.27 |
JavaScript 전역변수 (2) | 2024.06.22 |
History 그거 완전 퇴물 아니냐? (1) | 2024.06.12 |