랙시컬 스코프가 무엇인지 알기에 앞서,
스코프 그리고 스코피 체인을 알아본 후 렉시컬 스코프에 대해 알아보자
1. 스코프(Scope)?
- 스코프는 말 그대로 범위를 뜻하며, 변수에 접근 가능한 범위를 말한다.
- 스코프는 해당 변수가 어디서(where) 선언되었는지에 따라 결정되며, 크게 전역, 지역 스코프로 나뉜다.
- 전역스코프는 블록 바깥({}) 영역을 의미하여, 블록 바깥에 선언된 변수를 전역변수라고 부른다.
- 전역변수는 어떤 함수, 블록에서든 호출할 수 있다.
const variable = 1; // 전역변수
function print() {
console.log(variable); // 1
}
console.log(variable); // 1
- 이와 달리 지역스코프는 블록({}), 함수 내부 영역을 뜻하여, 지역스코프에 선언된 변수는 지역변수이다.
- 전역변수와 달리 어디에서든 호출할 수 없으며 함수, 블록 내에서만 접근할 수 있다.
function print() {
const test = 12;
console.log(test) // 12
}
console.log(test) // test is undefined
- 이러한 지역변수는 변수 선언 방식에 따라 스코프가 나뉘는데,
var
로 선언한 경우 함수 스코프,let
&const
로 선언한 경우 블록 스코프가 된다.- 그렇다면, 함수, 블록 스코프는 무엇일까?
2. 함수 스코프, 블록 스코프
(1) 함수 스코프
- 함수 몸체에 선언된 변수는 해당 함수에서만 유효하며, 이 유효범위를 함수 스코프라고 부른다.
- var로 선언된 변수는 모두 함수 스코프를 따른다.
- 아래 코드에서 함수 내부에서 var로 변수를 선언한 모습이다.
function test() {
var variable = 'world';
}
console.log(variable) // hello is not defined
- variable을 함수 test()에 선언되었으며, variable는 함수스코프에 있다.
- 그렇기 때문에 함수 바깥에서 variable를 호출하면 undefined 에러가 발생한다.
- 만약 블록에서 var로 변수를 선언하면 어떻게 될까?
- 앞서 언급했듯이 var은 함수 스코프를 따르므로, 블록과 상관없이 호출가능하다.
{
var variable = 'world';
}
console.log(variable) // world
(2) 블록 스코프
- 블록 몸체에 선언된 변수는 해당 블록에서만 유효하며, 이 유효범위를 블록 스코프라고 부른다.
- let, const로 선언한 변수는 블록 스코프를 따른다.
- 아래 코드에서 블록 내부에서 const로 변수를 선언한 모습이다.
{
const variable = 'world';
console.log(variable) // world
}
- variable은 블록 내부에서 선언되었으며, 블록 내부에서는 해당 변수에 접근할 수 있다.
{
const variable = 'world';
}
console.log(hello) // hello is not defined
- 하지만 블록 바깥에서 variable에 접근하려고 하면, undefined 에러가 발생한다.
- 그 이유는 variable는 블록 스코프에 속하는 변수이기 때문이다.
function test() { // block
const hello = 'world';
}
console.log(hello) // world
- 만약 함수 내부에서 const로 변수를 선언하면 어떻게 될까?
- const는 블록스코프를 따르기 때문에 함수 내부에서 선언해도 바깥에서 호출할 수 있다!
3. 스코프 체인?
- js 스코프에 특징이 있는데 그건 바로 스코프 체인이다.
- 스코프 체인이란, 현재 스코프에 해당 변수가 없다면 상위 스코프에서 찾는 걸 말한다.
- print()에서 variable을 출력하고자 한다.
const variable = 'world';
function print(){
console.log(variable);
}
- 하지만 print() 내부에는 해당 변수가 없다!
- 이 경우 스코프 체인으로 인해 상위 스코프를 탐색하게 된다.
- print()의 상위스코프에 variable이 존재하므로 이 변수를 사용하게 된다.
const variable = 1;
function print(){
console.log(variable);
}
print(); // world
4) 랙시컬 스코프?
- 랙시컬 스코프는 함수가 어디에 선언되어 있느냐에 따라 결정된다.
- 다른 말로 정적 스코프라고 부르며, js에서 함수는 정적 스코프를 따른다.
- 함수가 중첩되어 있을 시, 내부 함수에 호출 대상이 없다면 상위스코프에서 찾는다. (스코프 체인 특성)
🤔 그렇다면 상위 스코프의 기준은 무엇일까?
- 상위스코프는 함수가 어디에 선언되어있는지에 따라 결정된다.
- 만약 A함수 내부에서 B함수가 선언되어 있다면, B함수의 상위스코프는 A함수이다.
function A(){ // A는 B의 상위 스코프임
var variable = 'world';
function B(){ // B는 A에 선언되어 있음
console.log(variable);
}
B();
}
A(); // world
🤔 만약 아래와 같은 경우에는 결과는 어떻게 될까?
var variable = 'world';
function A(){
var variable = 'test';
B();
}
function B(){
console.log(variable);
}
A();
- 답은 바로 world이다.
- 이유는 차근차근 살펴보자.
var variable = 'world';
- world를 값으로 가지는 variable는 전역변수이다.
function A(){
var variable = 'test';
B();
}
- 그리고 A()내부에는 variable변수가 선언되어 있으며 B()를 호출한다.
function B(){
console.log(variable);
}
- B()는 variable을 출력하는 함수로 전역레벨에 선언되어 있다.
- 그리고 선언된 B()의 가장 가까운 상위스코프는 전역 변수 variable이다.
- 앞서 언급했듯이 함수는 랙시컬 스코프를 따르며, 선언된 위치를 기준으로 상위 스코프를 찾는다.
- 그렇기 때문에 variable 출력 결과가 전역 변수 variable가 나오는 것이다.
var variable = 'world';
function A(){
var variable = 'test';
B();
}
function B(){
console.log(variable);
}
A(); // world
반응형
'개발 기술 > 개발 이야기' 카테고리의 다른 글
클로저는 무엇일까? (feat. 외부, 내부 함수, 랙시컬 스코프) (0) | 2021.11.29 |
---|---|
call, apply, bind의 차이 (0) | 2021.11.25 |
promise와 async await의 차이점 (0) | 2021.11.17 |
비동기 처리, promise와 async await (0) | 2021.11.15 |
프로토타입 (feat. 매운 맛🔥) (0) | 2021.11.04 |
댓글