Chapter 13 스코프
in Frontend / Js / Javascript
Scope
13.1 스코프란?
- 유효범위
- 식별자가 유효한 범위 (선언된 위치에 의해)
- aka 식별자를 검색할 때 사용하는 규칙 (결정)
- ex: 여러
x
변수 중 어떤x
를 사용할지 결정
- ex: 여러
동일한 식별자여도 스코프가 다르면 다른 변수로 취급
- \(\rightarrow\) 스코프 개념이 존재하기 때문에 변수명이 겹쳐도 괜찮다
- ex: 폴더+파일 예시- 동일 파일명이라도 폴더가 다르면 다른 파일로 인식
var
: 함수레벨 스코프, 같은 스코프 내에 중복 선언 허용- ⚠️ 의도치 않게 변수값 재할당되는 부작용
let
,const
: 블록레벨 스코프, 같은 스코프 내에 중복 선언 불가- 중복 선언 시 SyntaxError 발생
13.2 스코프의 종류
전역 스코프 (Global Scope)
- 코드 어디서든 참조 가능
- 최상위 스코프
지역 스코프 (Local Scope)
- 함수 스코프: 함수 몸체 내부
- 블록 스코프: 중괄호 내부
13.3 스코프 체인
- 계층적 구조, 스코프 체인
- 변수 참조하는 코드의 스코프에서 시작해서 상위 스코프로 이동
- 실체로 존재함!!!
- JS Engine에 Lexical Environment가 특정 자료구조를 사용하여 스코프 체인 관리
- 렉시컬 환경: 실행 컨텍스트의 렉시컬 환경을 단방향으로 연결 (chaining)
- 상속과 유사함
- 변수 뿐만이 아니라 함수도 스코프 체인에 묶임
📌 스코프: 식별자를 검색하는 규칙!
13.4 함수 레벨 스코프
var
: 코드블록이 아니라 함수 내에서 스코프 생김코드 블록:
{ }
로 묶인 코드 (if
,for
,while
…)var x = 1; if (true) { var x = 10; } console.log(x); // 10
var i = 10; for (var i = 0; i < 5; i++) { console.log(i); // 0 1 2 3 4 } console.log(i); // 5
- 🛑 의도치 않은 변수의 값이 재할당
13.5 블록 레벨 스코프
- dynamic scope: 실행 시점에 따라 스코프 결정 (어디서 호출)
- 호출되는 시점에 동적으로 상위 스코프를 결정
- lexical scope: 선언 시점에 따라 스코프 결정 (어디서 정의)
- aka static scope
- JS 포함 대부분 언어가 lexical scope 사용
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x); // 1
}
foo(); // 1, 동적 scope라면 10이었을 것 (foo에서 호출했으므로)
bar(); // 1
2회독 노트
- 하나의 값은 유일한 식별자에 연결 (Name binding) 되어야 함. 같은 스코프 내에 같은 이름의 식별자 존재하면 안됨
- 스코프는 네임스페이스이다
- A namespace provides a container to hold things like functions, classes and constants as a way to group them together logically and to help avoid conflicts.
- JS 는 다른 언어와 다르게 function-level scope 만 생성함 (
var
)- 하지만 ES6에서 공개된
const
와let
은 block level scoping을 지원
- 하지만 ES6에서 공개된
\(Q\). block level 을 지원하기 시작했는데,
var
은 선언 시 scope가 block이면 무시하고 그 위가 global 또는 function-level 일때까지 타고 올라가서 등록하는걸까?if (true) { // 여기서 block scope 생성 (SCOPE B) let x = 10; // SCOPE B 내에서 선언된 변수 const y = 20; // SCOPE B 내에서 선언된 변수 var z = 30; // GLOBAL SCOPE 에 생성된 변수? console.log(x); // 10 console.log(y); // 20 console.log(z); // 30 } console.log(x); // ReferenceError: x is not defined console.log(y); // ReferenceError: y is not defined console.log(z); // 30
- GPT 답변: 네, 정확히 이해하셨습니다! var는 block-level scope를 무시하고, 가장 가까운 function-level 또는 global scope에 변수를 등록합니다. 이 경우 var z는 if 블록을 무시하고 Global Scope에 바인딩됩니다.