스코프(Scope)란?
스코프(Scope, 유효범위)는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다. 자바스크립트는 이 규칙대로 식별자를 찾는다.
자바스크립트에서 스코프는 전역(global)과 지역(local)으로 2가지 타입이 있다.
- 전역 스코프(Global Scope)
코드 어디에서든지 참조할 수 있다. - 지역 스코프(Local Scope)
함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다. (함수 스코프와 블록 스코프가 있다.)
모든 변수는 스코프를 갖는다. 변수의 관점에서 스코프를 구분하면 2가지로 나눌 수 있다.
- 전역 변수(Global Variable)
전역에서 선언된 변수이며 어디에든 참조할 수 있다. - 지역 변수(Local Variable)
지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.
자바스크립트에서 함수를 선언하면 함수를 선언할 때마다 새로운 스코프를 생성하게 된다. 그러므로 함수 몸체에서 선언한 변수는 해당 함수 몸체 안에서만 접근 할 수 있는데, 이걸 함수 스코프(function-scoped)라고 한다. 함수 스코프가 바로 지역 스코프의 예라고 할 수 있다.
var a = 1; // 전역 스코프
function print() { //지역(함수) 스코프
var a = 111;
console.log(a);
}
print(); // '111' 출력
console.log(a); // '1' 출력
예제의 print 함수에서 console.log(a);는 a를 출력하기 위해 자신의 함수 스코프 안에 변수 a가 있는지 찾아본다. var a=111;을 찾아낸다면 111을 console에 출력하고 함수는 자신의 사명을 다 하게 된다.
만약 print함수 안에 변수 a의 선언을 지우게 된다면 console에는 어떤 값이 출력될까?
→ 전역 스코프에 선언되어 있는 a의 값인 1이 출력된다. 이는Scope Chain에 의해 일어나는 현상인데, 현재 자신의 scope에서 사용하고자 하는 변수가 없다면 Scope Chain을 통해 해당 변수를 찾게된다.
1) var, 함수 스코프(Function Scope)
var 은 함수에서만 지역변수가 되는 함수레벨 스코프만을 가진다. 이는 생성된 함수 내에서만 사용할 수 있으며, 함수 내부에서 생성되지 않은 경우 전역 범위를 가진다.
function a() {
var variable = 1;
console.log(variable); // 1
}
a(); // 1
console.log(variable) // ReferenceError: variable is not defined
if (true) {
var variable = 1;
}
console.log(variable) // 1
예제를 보면 함수 내부에서 선언된 var키워드로 선언된 변수 variable은 함수 외부에서 접근 할 수 없다. variable변수는 전역변수로 선언된 것이 아니기에 a()함수 스코프 내에서만 접근이 가능하다. 하지만 if문, loop문 등과 같은 다른 유형의 블록에서는 스코프로 간주되지 않는다.
2) let, const, 블록 스코프(Block Scope)
ES6에서는 변수를 선언하는 대체 방법으로 let , const 키워드가 도입되었으며, 이 둘은 블록 스코프를 가진다. 함수 스코프만 스코프로 취급하는 var과 달리 블록 스코프에서는 모든 블록이 스코프가 된다. 블록이란 여는 중괄호{}의 집합이다.
function a() {
const constance = 1;
}
console.log(constance) // ReferenceError: constance is not defined
if (true) {
let string = 'hello';
console.log(string) // hello
}
console.log(string) // ReferenceError: string is not defined
위의 예제는 var 키워드를 let 키워드로만 대체하여 변수를 선언한 것이다. let 키워드로 선언된 string 변수는 콘솔에서 타입 에러를 일으킨다. let, const 키워드는 var 키워드와 달리 함수 스코프가 아닌 블록 스코프를 가지고 있기 때문이다.
3) 렉시컬 스코프(Lexical Scope)
자바 스크립트는 기본적으로 렉시컬 스코프를 따른다. 렉시컬 스코프란 중첩된 함수 그룹에서 내부 함수가 상위 범위의 변수 및 기타 리소스에 액세스 할 수 있음을 의미한다. 즉, 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정한다는 뜻이며, 가장 중요한 점은 함수를 어디서 호출하는지가 아니라 함수를 선언위치에 따라 결정되는 상위 스코프이다. 다른 말로 정적 스코프(Static Scope)라 부르기도 한다.
var a = 1; // Lexical Scope에서 가장 가까운 변수
function changePrint (){
console.log(a);
}
function change (){
var a = 100;
changePrint();
}
change(); // 1
var a = 1;
function change (){
function changePrint (){
console.log(a);
}
var a = 100; // Lexical Scope에서 가장 가까운 변수
changePrint();
}
change(); // 100
위의 예제에서 출력값은 100이 아니라 1이 된다. change 함수를 통해 a의 값이 새로 할당되었다고 하더라도, changePrint 함수가 실행될 때 렉시컬 스코프의 범위를 따른다. console.log(a); 는 changePrint 함수를 감싸는 범위인 전역 변수로 선언되어있는 var a=1; 을 인자로 받게 된다.
4) 다이나믹 스코프(Dynamic Scope)
다이나믹 스코프는 함수 호출 위치에 따라 결정되는 상위 스코프이다. (자바스크립트에서는 이를 구현 불가능하다)
var a = 1;
function changePrint (){
console.log(a);
}
function change (){
var a = 100; // Dynamic Scope에서 가장 가까운 byeonSu변수
changePrint();
}
change(); //100
change 함수 안에서 호출된 changePrint 함수가 호출 위치에 가까운 var a=100; 의 값을 console.log에 전달할 것이다. 따라서 100이 출력된다.
[JS] 6. 함수 스코프 & 블록 스코프 & 렉시컬 스코프
자바스크립트 - 렉시컬 스코프(Lexical Scope)
Lexical Scope vs Dynamic Scope
스코프 체인(Scope Chain)이란?
스코프 체인은 일종의 리스트로서 전역객체와 중첩된 함수의 스코프 레퍼런스를 차례대로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결(chain)되고 있는지 보여주는 것을 말한다. 스코프 체인을 이해하기 위해 먼저 자바스크립트의 실행 컨텍스트를 알아야 한다.
실행 컨텍스트(Execution context)
실행 컨텍스트는 우리가 작성한 코드가 실행되는 환경을 말하며, scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리를 말한다. 그리고 이 실행 컨텍스트에서는 두 개의 실행 컨텍스트가 존재한다.
- 글로벌 실행 컨텍스트(Global Execution Context)
코드가 실행되기 전에 생성이 되며, 함수 내에 없는 코드는 모두 전역 실행 컨텍스트 안에 존재한다. 그렇기 때문에 자바스크립트 엔진은 일부 자바스크립트 코드를 실행할 때마다 글로벌 실행 컨텍스트를 작성한다. 특징으로는 무조건 하나의 전역 실행 컨텍스트만이 존재하며, 애플리케이션이 종료될 때(웹페이지에서 나가거나 브라우저를 닫을 때)까지 유지하는 것이다. - 함수 실행 컨텍스트(Functional Execution Context)
전역 실행 컨텍스트가 생성된 후, 함수가 실행(호출) 될때마다 새로운 실행 컨텍스트가 작성된다.
실행 컨텍스트에서 스코프 체인이 작동하는 방법
실행 컨텍스트는 LIFO(Last in, First out) 구조의 스택으로, 코드 실행 중에 생성된 모든 실행 컨텍스트를 저장하는데 사용된다. 실행 컨텍스트가 실행되면, 엔진이 스코프 체인을 통해 렉시컬 스코프를 먼저 파악한다. 그리고 함수가 중첩 상태일 때 하위 함수 내에서 상위 함수의 스코프와 전역 스코프까지 참조할 수 있는데 이것을 스코프 체인을 통해 탐색하는 것이다.
자바스크립트 - 스코프 체인(scope chain)란?
'자바스크립트' 카테고리의 다른 글
| this (0) | 2023.03.17 |
|---|---|
| callback, promise, async/await (0) | 2023.03.14 |
| 이벤트 위임 (0) | 2023.03.11 |
| 자바스크립트의 배열 (0) | 2023.03.08 |
| Hoisting과 Temporal Dead Zone (0) | 2023.03.06 |