# scope
참조 대상 식별자(변수)를 찾아내기 위한 규칙
식별자는 자신을 참조할 수 있는 범위 (렉시컬 환경)를 갖는다.
스코프는 식별자 이름의 충돌을 방지
어떠한 변수가 스코프 안에 선언됐을때, 해당 스코프 안에서는 변수에 접근해서 읽거나 쓸 수 있고, 스코프 밖에서는 해당 변수에 접근할 수 없다.
# 스코프의 구분
전역 스코프
코드 어디에서든 참조 가능
지역 스코프(Local Scope/Function-level Scope)
함수 코드 블록이 만든 스코프
- 변수 관점
전역 변수
전역에서 선언된 변수, 어디든 참조 가능
지역 변수
지역(함수) 내에서 선언된 변수, 지역의 하부 지역에서만 참조 가능
# 전역 스코프
var
키워드로 선언한전역변수
는브라우저
에서 전역객체window의 프로퍼티
이다.- 자바스크립트는 타 언어와 달리, 특별한 시작점(Entry Point)가 없어서 전역에 변수나 함수를 선언하기 쉽다.
- c 언어의 경우 main 이 함수의 시작점
- 전역 변수의 사용은 변수이름의 중복이 될 수 있다.
- 의도치 않은 재할당에 의해 코드를 예측하기 어렵게 만든다.
# 블록 레벨 스코프 (block-level scope)
if, while, for { ... }
# Switch 안에서의 let과 const🔗
case
문은 별도의 Lexical Scope가 없다.
(Uncaught SyntaxError: Identifier 'foo' has already been declared)
switch (foo) {
case 1:
let foo = 1;
break;
case 2:
const foo = 2;
break;
/* ... */
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
블록 스코프가 필요한 곳의 case 문을 {} 로 감싼다.
case 1: {
let foo = 1;
break;
}
1
2
3
4
2
3
4
# 함수 레벨 스코프 (Function-level scope)
- function() {...}
# 렉시컬 스코프
함수호출위치가 아닌, 함수 선언 위치에 따라 결정된다.
# 암묵적 전역(implicit global)
ES6 아래의, 엄격모드가 아닐때,
변수를 선언 없이 사용했을 경우, y = 20
- JS 엔진은
window.y = 20
으로 해석하여 프로퍼티를 생성 - 변수가 아니므로 호이스팅이 발생하지 않는다.
# 즉시실행 함수를 이용한 전역 변수 사용 억제 (IIFE)
- 즉시 실행되고 전역에서 바로 사라진다.
# 스코프체인
식별자를 찾는 일련의 과정
변수가 스코프 안에 선언되지 않았다면, 그 변수를 찾기 위해 부모 스코프로 올라가고, 거기에도 없다면 또 그 부모 스코프에 올라가서 찾는다.
- 코드에서 변수에 접근할 땐, 먼저 렉시컬 환경을 검색 범위로 잡는다.
- 내부 렉시컬 환경에서 원하는 변수를 찾기 못하면 검색 범위를 내부 렉시컬 환경이 참조하는 외부 렉시컬 환경으로 확장한다.
- 전역 렉시컬 환경으로 확장될 때까지 반복된다.
# 전역렉시컬에서 변수를 프로퍼티를 찾지 못했을 때,
- 엄격모드 : 에러 발생
- 비엄격모드 : 새로운 변수가 만들어 진다.
- 하위호환성을 위해 남아있는 기능