이 게시물은 SW마에스트로 연수생 간 진행한 Modern JavaScript DeepDive 스터디 개인 정리 내용입니다.
되도록 책의 내용을 그대로 적기보단 개인적으로 인상깊었던 부분을 구어체로 풀어쓰려 노력했습니다.
Modern JavaScript Deep Dive
Chapter _ 13 스코프
스코프란?
스코프는 [ 식별자가 유효한 범위 ] 를 의미하며 자바스크립트에서 기본적이고 “또” 중요한 개념 중 하나입니다.
함수에서 매개변수는 함수의 몸체에서만 참조가 가능하고 외부에선 참조할 수 없었던 것이 스코프의 여러가지 활용 중 하나입니다.
모든 식별자들은 자신이 선언된 위치에 따라 자신을 참조할 수 있는 [ 유효한 ] 범위가 결정됩니다.
1
2
3
4
5
6
7
var x = 'global'
function foo() {
var x = 'local'
console.log(x)
}
console.log(x)
위 코드에서 x 는 함수 바깥에, 그리고 안쪽에 같은 식별자 이름으로 위치하고 있습니다. 자바스크립트 엔진은 각각의 콘솔 로그 요청에서 어떤 x 를 참조해야할 지 결정해야만 합니다. 이러한 결정을 내리는 과정을 식별자 결정 이라고 하며, 스코프는 식별자를 결정하는 규칙이라고도 할 수 있겠습니다.
앞선 예제에서 볼 수 있듯이 만약 x 가 두개 동시에 존재할 수 있다면 식별자 결정에서 자바스크립트 엔진은 충돌을 일으킬 것이고, 매 변수마다 새로운 식별자 이름을 강제당할 것입니다. ( 지금도 변수 이름짓는게 고통인데 )
스코프의 종류
코드는 전역 ( global ) 과 지역 ( local ) 로 구분할 수 있습니다. 아마도 이 부분은 이전 다른 프로그래밍 언어에서 통용되는 개념을 채용해 온 부분이 아닐까 싶습니다.
앞서서 변수는 자신이 선언된 위치에 따라 자신을 참조할 수 있는 유효 범위가 결정된다고 했었습니다.
전역에서 선언된 변수는 전역변수, 지역에서 선언된 변수는 지역변수. 변수는 이렇게 크게 두 그룹으로 구분됩니다.
따라서, 전역에 선언된 전역변수는 전역 스코프를 갖게 되고 지역에 선언된 지역 변수는 지역 스코프를 갖게 됩니다.
마지막으로 전역에 선언된 전역변수는 전역 스코프를 갖기에 전역에서 유효하며, 지역에 선언된 지역변수는 지역 스코프를 갖기에 지역에서만 유효하다. 라고 정리할 수 있겠습니다.
스코프 체인
함수가 전역에 선언되고 또 다시 그 함수 안에 함수가 선언되듯 중첩될 수 있듯이 스코프 또한 중첩될 수 있습니다.
모든 스코프는 하나의 계층적 구조로 연결되며 이를 스코프 체인이라고 칭합니다.
전역에 선언된 outer 함수 그리고 outer 함수 안에 선언된 inner 함수가 존재할 때, 변수를 참조해야 하는 자바스크립트 엔진은 스코프를 확인하게 됩니다.
이 때, 스코프 체인을 통해 우선 inner 함수에서 시작해서 outer ⇒ 전역 으로 거슬러 올라가는 스코프 탐색 시퀀스를 스코프 체인 이라고 이해하면 될 것 같습니다.
위의 예시와 같이 하위 스코프에선 거슬러 올라가 상위 스코프의 변수를 참조 할 수 있습니다.
하지만 반대의 경우는 불가능합니다.
전역 스코프에서 다른 지역 스코프의 참조는 불가능하며 이것이 추후에 나올 개념인 클로저의 간단한 요약이라고 볼 수 있겠습니다.
함수 레벨 스코프
이미 앞에 계속해서 예시로 함수를 예시로 들었지만, 지역 ( local ) 은 함수를, 지역 스코프는 함수 내부의 코드 블럭을 의미합니다.
하지만 대부분의 프로그래밍 언어들은 함수 몸체뿐만 아니라 모든 코드블럭 ( if, for ,while ) 에서도 지역 스코프를 생성합니다.
현재는 거의 사용되지 않는 var 키워드가 바로 함수 레벨 스코프만을 지원합니다.
렉시컬 스코프
1
2
3
4
5
6
7
8
9
10
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x)
}
foo()
bar()
위와 같은 코드에서 10, 1 이 출력될 것이라 생각할 수 있지만 실제론 1,1 이 출력됩니다.
그 이유가 바로 렉시컬 스코프 때문이라고 할 수 있습니다.
앞서서 10, 1 을 예상했다면 함수가 호출되는 시점을 기준으로 스코프를 정의하는 동적 스코프.
1,1 을 예상했다면 현재 자바스크립트와 대다수의 프로그래밍 언어가 사용하고 있는 렉시컬 스코프는 정의되는 시점을 기준으로 스코프를 정의하는 정적 스코프 입니다.
렉시컬 스코프는 실행 컨텍스트, 클로저와 긴밀한 관계가 있기 때문에 그 때 다시한번 알아보도록 하겠습니다.
