안녕하세요! 이번 포스팅에서는 자바스크립트의 중요한 개념인 스코프(Scope)에 대해 다뤄보겠습니다. 이 두 가지는 자바스크립트를 이해하고 활용하는 데 꼭 알아야 하는 핵심 개념들입니다. 헷갈릴 수 있는 부분이 많아서 자세히 정리해보았습니다.
자바스크립트(JavaScript)의 스코프
목차
스코프 (Scope)란?
스코프 (scope)는 식별자(identifier,변수,함수,클래스의이름)가 유효한범위를 의미합니다.자바스크립트에서 스코프는 크게 전역 스코프와지역 스코프두 가지로 나눌 수 있습니다.
- 스코프가 필요한 이유
스코프가 없다면 같은 이름을 갖는 식별자들끼리 출돌이 발생할 수 있습니다.
const value = 'a'; function scopeFunc { const value = 'b'; console.log(value); // b } console.log(value); // a
위 예시를 보면 value가 중복 선언 되었지만 스코프가 있어 서로 다른 값이 출력되고 있습니다. 스코프가 없었다면 const에 값을 재할당했기 때문에 에러가 발생했을 것입니다.
스코프의 종류
- 전역 스코프(Global Scope)
전역 스코프는 프로그램 전체에서 접근할 수 있는 범위입니다. 함수나 블록(if문, for문, while문 등)에서 가장 바깥에 있는 영역에서 선언된 변수는 전역 변수가 되고, 어디에서든지 접근할 수 있습니다.
let globalValue = "Global Value"; function printGlobal() { console.log(globalValue) // globalValue는 전역 변수로 함수 내에서도 접근 가능 } printGlobal() // Global Value
- 지역 스코프(Local Scope)
지역 스코프는 블록이나 함수 내부에서만 유효한 범위입니다. 지역 스코프 내에서 선언된 변수는 지역 스코프 자신과 하위 지역 스코프에서만 참조 가능합니다. 지역 스코프에는 함수 스코프와 블록 스코프가 존재합니다.
function localPrint() { let localValue = "Local Value"; console.log(localValue); // localValue는 지역변수로 함수 내부에서 접근 가능 } localPrint(); // Local Value console.log(localValue); // ReferenceError: localVar is not defined
함수 스코프와 블록 스코프
- 블록 스코프(Block Scope)
자바스크립트는 함수 레벨 스코프를 따르는 언어입니다. 하지만 ES6부터 let과 const 키워드가 도입되면서 블록 레벨 스코프를 사용할 수 있게 되었습니다. 블록 스코프는 중괄호({})로 묶인 범위를 의미합니다.
{ let a = "A"; var b = "B"; console.log(a); // A console.log(b); // B } console.log(a); // ReferenceError: a is not defined console.log(b); // B
위의 예제 결과를 보면 let 키워드로 선언한 a는 블록 스코프 범위 밖에서 호출이 안되는 것을 볼 수 있습니다. 하지만 var 키워드로 선언한 b는 블록 스코프 범위 밖에서도 호출이 되는 것을 볼 수 있습니다. 이는 var가 함수 스코프를 따르기 때문입니다. - 함수 스코프(Fucntion Scope)
함수 스코프는 함수 블록만 지역 스코프로 인정합니다. 함수 내에서 선언된 변수는 함수 내에서만 참조 할 수 있고, 함수 외에 블록(중괄호로 묶인 범위)는 지역 스코프로 인정하지 않아 전역에서 지역 변수를 참조 할 수 있습니다.
var a = 'a'; if(true) { var a = 'b'; } console.log(a); // b
위의 예제 결과를 보면 a의 출력이 'b'로 나오는 것을 볼 수 있습니다. 이는 var 키워드가 함수 스코프이기 때문입니다. 아래 예제로 간단히 설명 드리겠습니다.
var a = 'a'; if(true) { // var가 함수 스코프이기 때문에 블록({}) 영역을 무시하고 전역으로 사용됩니다. var a = 'b'; } ---- 위 내용을 간단히 하면 ---- var a = 'a'; var a = 'b'; console.log('a'); // b
스코프 체인 (Scope Chain)
함수 내에 또 다른 함수가 존재할 수 있고, 이런 경우 스코프가 겹칠 수 있습니다. 이렇게 상위 스코프와 하위 스코프가 계층적으로 연결된 것을 스코프 체인이라고 합니다. 자바스크립트의 엔진은 단방향으로 이동하면서 변수를 탐색합니다.
let globalValue = 'global';
function outer() {
let outerValue = 'outer';
function inner() {
let innerValue = 'inner';
console.log(innerValue); // inner
console.log(outerValue); // outer
console.log(globalValue); // global
}
inner();
}
outer();
위 예제를 보면 inner() 함수 스코프에서 outerValue를 탐색하기 위해 outer() 스코프로 이동하고, globalValue를 찾기 위해 전역 스코프까지 상위 스코프로 이동한 것을 볼 수 있습니다. 만약 상위 스코프에서 하위 스코프의 변수를 참조하면 어떻게 될까요?
let globalValue = 'global';
function outer() {
let outerValue = 'outer';
console.log(innerValue); // ReferenceError: innerValue is not defined
function inner() {
let innerValue = 'inner';
console.log(innerValue);
console.log(outerValue);
console.log(globalValue);
}
inner();
}
outer();
결과는 innerValue가 선언되지 않았다는 에러를 출력합니다. 이는 자바스크립트 엔진이 하위 스코프에서 상위 스코프로 상향식 단방향 탐색을 하기 때문입니다.
렉시컬 스코프
렉시컬 스코프는 함수가 선언된 위치에 따라 상위 스코프가 결정되는 방식입니다. 자바스크립트를 포함한 대부분의 언어는 렉시컬 스코프를 따릅니다.
let x = 0;
function a() {
let x = 1;
b();
}
function b() {
console.log(x);
}
a(); // 0
b(); // 0
위 예제의 결과를 확인해 보면 0, 0이 출력된 것을 볼 수 있다. 그 이유는 a 함수 스코프 내에서 b 함수가 호출 되었지만, b 함수가 선언된 위치가 전역 스코프 이기 때문이다.
자바스크립트의 스코프는 처음에는 다소 헷갈릴 수 있지만, 잘 이해하면 자바스크립트의 유연한 기능들을 제대로 활용할 수 있습니다. 스코프는 변수의 유효 범위를 결정하고, 자바스크립트는 함수 단위로 스코프를 구분합니다.
자바스크립트는 상향식(단방향) 탐색을 하고, 함수가 어디에 선언되었는지에 따라 상위 스코프가 결정된다는 사실 꼭 기억하셨으면 좋겠습니다!
추천글
2024.09.12 - [개발 공부 일지/JavaScript] - [JS] 자바스크립트 함수
'개발 공부 일지 > JavaScript' 카테고리의 다른 글
[JS] 얕은 복사, 깊은 복사 (0) | 2024.09.19 |
---|---|
[JS] 자바스크립트의 배열 (4) | 2024.09.14 |
[JS] 자바스크립트 함수 (1) | 2024.09.12 |
[JS] 자바스크립트의 자료형 (2) | 2024.09.12 |
[JS] Input 이벤트 (9) | 2024.09.11 |