웹/JavaScript

JavaScript Scope chain과 Lexical scoping

클라우드아실 2021. 1. 10. 21:54

JavaScript Scope chain과 Lexical scoping

 : 스코프는 변수의 유효범위를 나타냅니다. 함수는 중첩될 수 있기 때문에 함수의 지역 스코프도 중첩될 수 있습니다. 이렇게 스코프가 함수의 중첩에 의해 계층적인 구조를 갖게 되었을 때, 식별자를 유효범위 안에서부터 바깥쪽으로 차례대로 검색해 나가는 것을 스코프 체인이라고 합니다.

let x = 'global x';

function outer() {
  console.log(x); // 'global x'
  x = 'outer x';
  
function inner() {
  console.log(x); //'outer x'
}

inner();
}

outer();

console.log(x); //'outer x'
  • 4번째 줄 x는 호출 되기 전 전역변수 x가 가장 먼저 선언되었기 때문에 첫번째 줄 전역변수 x를 참조합니다.
  • 5번째 줄 x가 재할당 되었습니다.
  • 8번째 줄 x도 함수 내에 선언된 변수가 없기 때문에 상위의 스코프에서 해당 변수명을 찾아 참조합니다.
  • 16번째 줄 x는 5번째 줄 x가 전역변수 x를 재할당 했기 때문에 최종적으로 변경된 전역변수를 참조합니다.
  • 이렇게 상위 스코프, 하위 스코프로 계층 구조를 갖는 걸 스코프 체인이라고 합니다.

Lexical scoping

 : 스코프는 함수를 호출할 때가 아니라 선언할 때 결정합니다. 즉 함수의 상위 스코프는 언제나 자신이 정의된 스코프를 기준으로 찾게 됩니다.

let x = 'global x';

function outer() {
  console.log(x); // 'global x'
  x = 'outer x';
  }
  
function inner() {
  console.log(x); //'global x'
}

inner();

outer();

console.log(x); // outer x
  • 4번째 줄 x는 함수 내 동일한 변수명이 없어서 상위 스코프의 전역변수 x를 참조합니다.
  • 9번째 줄 x는 함수 내 동일한 변수명이 없어서 상위 스코프의 전역변수 x를 참조합니다.
  • 이 때 각 함수가 선언될 당시 outer함수는 실행전으로 9번째 줄 x는 5번째 줄 x가 아니라 전역변수 x를 참조합니다. 
  • 마지막 16번째 줄 x는 함수 실행이 되고 이미 전역변수 x가 outer x로 재할당 된 뒤기 때문에 결과값이 다릅니다.
  • 이렇게 선언 기준으로 스코프를 결정 하는 것을 lexical scoping라고 합니다.

 

정리

  • Scope chain은 식별자를 유효범위 안에서부터 바깥쪽으로 차례대로 검색해 나가는 것
  • 스코프는 함수를 선언할 때 결정된다. 

 

 

참고

모던 자바스크립트 튜토리얼 - 변수의 유효범위와 클로저

생활코딩 - 유효범위

제로초 - 함수의 범위(scope)

TCPSCHOOL.COM 변수의 유효범위

MDN 스코프

PoiemaWeb - 스코프

Xedni's Lab - 스코프