📌 스코프
각 식별자들의 유효 범위, 참조 대상 식별자를 찾아내기 위한 규칙이다. 이 규칙으로 자바스크립트는 식별차를 검색할 때 사용하는 규칙으로 작용한다.
if, for, function과 같은 범위를 통해 각자 자신이 유효한 범위를 갖는다.
이러한 규칙때문에 같은 이름일 경우에 충돌이 나지 않는다.
- Global Scope
- Function Scope
- Block Scope
전역 스코프와 지역 스코프
전역 스코프(Global Scope)
자바스크립트 코드의 최상위 레벨에 해당하는 스코프로 함수 어디에서든 접근이 가능하다.
지역 스코프(Local Scope)
특정 함수에 해당하는 스코프로 해당 함수 자신과 하위 함수에서만 자원에 접근이 가능하다.
전역 스코프 이외의 스코프들을 의미한다. (함수레벨 스코프, 블록 스코프, 모듈 스코프 등이 있다.)
Function-level Scope
특정 함수 내에 어떠한 블록이 있다면, 그 블록 내에 있는 변수는 해당 함수 내에서도 접근할 수 없고 오직 그 블록 내에서만 접근이 가능하다. 하지만 자바스크립트는 기본적으로 함수레벨 스코프를 따른다 함수 내에서 선언한 변수는 그 함수 내에서만 접근할 수 있고 함수 안의 블록에서 선언된 변수도 해당 함수 내에서 접근할 수 있다.
Block-level Scope
let과 const 키워드를 사용하여 변수를 선언하면 그 변수는 Block-level Scope를 가진다. let과 const 변수는 선언된 블록내에서만 유효하다.
📌 Lexical Scope
함수를 어디서 정의(선언)되었는지에 따라 상위 Scope가 결정된다. ➡️ 정의된 위치 기반, Static Scope
함수가 어디서 호출되었는지 X
동일 스코프의 변수는 실행 시간이 가장 늦을 곳의 값이 최종 할당된다.
🤔 Lexical Scope와 Dynamic Scope의 차이점
위에서 말했듯이 Dynamic Scope는 어디서 호출되었는지에 따라 Scope가 결정이 된다.
Lexical Scope Chain
스코프가 계층적으로 연결된 것을 말한다. 스코프 체인은 스코프가 중첩된 경우, 내부 함수에서 외부 함수의 변수에 접근할 수 있는 메커니즘을 말한다.
식별자의 유효범위를 안에서부터 바깥으로 차례대로 검색해나가는 것이다.
const x = 1;
function printX (){
console.log(x); // Lexical: 1, Dynamic: 100
}
function set100 (){
const x = 100;
printX();
}
set100();
Identifier resolution
코드 내에서 사용된 식별자를 찾아 가는 과정이다. 실제로 어떤 선언문에 연결되어 있는지를 찾아낸는 과정, 이과정에서 렉시컬 스코프 규칙에 따라현재 코드가 속한 스코프 체인을 따라 올라가면서 일치하는 선언이 있는지 확인한다.
Outer Lexical Environment Reference(OuterEnvReference => OuterEnv)
📌 렉시컬 환경(Lexical Environment)
- 환경 레코드(Enviroment Record)
- 외부 렉시컬 환경 참조(Outer Lexical Environment Reference)
이 둘로 구성되어 있다. 스코프 내의 변수와 함수를 정의, 관리하고 상위 컨텍스트에 대한 참조를 가지고 있다.
환경 레코드(Enviroment Record)
실행 스코프 안에 있는 식별자 정보들을 관리하는 객체로 JavaScript 엔진은 코드를 실행하기 전에 먼저 렉시컬 환경을 구성하며 환경 레코드에 식별자 정보들을 수집한다.
이 과정을 통해 해당 컨텍스트 내부의 변수명들을 모두 알고 있게 되는데 , 이 동작을 호이스팅이라고 한다.
전역 환경 레코드(GER : Global Environment Record)
- 최상위 스코프에 대한 바인딩을 제공한다.
객체 환경 레코드(OER : Object Environment Record)
- var, 전역변수, 선언문 전역 함수, global built-in bindings, FunctionDeclaration, Generator Delclaration 등 Variable Declaration bindings 가 포함된 전역 객체 참조
선언적 환경 레코드(DER : Declarative Environment Record)
- 객체 환경 레코드에 있는 것을 제외한 전역 코드의 모든 선언에 대한 바인딩을 포함한다.
- let, const 식별자 바인딩을 관리
함수 환경 레코드(Function Environment Record)
- 매개변수, argument, 내부 지역 변수 및 중첩 함수를 관리한다.
모듈 환경 레코드(Module Environment Record)
- 모듈의 외부 스코프를 나타낸다.
외부 렉시컬 환경 참조 (Outer Lexical Environment Reference)
현재 렉시컬 환경과 연결된 상위 렉시컬 환경을 참조하는 링크다.(단방향 Linked List)
함수가 호출된 위치가 아닌 정의된 위치에 따라 상위 스코프를 결정한다. 이를 통해 외부 스코프를 참조하는 스코프 체인이 동작한다.
📌 실행 컨텍스트
실행할 코드에 제공할 환경 정보들을 저장하고 있는 객체로 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다고 볼 수 있다.
❓ 환경정보
코드에 선언된 변수, 함수, 스코프 this, argument등을 의미한다.
자바스크립트 엔진이 코드를 실행하기 위해서는 코드에 대한 정보들이 필요하기 때문에 환경 정보를 모아 두는 객체인 실행 컨텍스트를 둔 것이다.
실행 컨텍스트가 활성화 될 때, JavaScript엔진은 실행에 필요한 환경들을 수집한다. 개발자가 직접 접근, 조작이 불가능 하다.
Execution Context Stack(ECS)를 통해 실행 컨텍스트를 관리하고 실행 순서를 보장한다.
또한 렉시컬 환경을 통해 스코프와 식별자를 관리한다.
실행컨텍스트는 2단계, 실행과 평가가 나눠진다.
평가 과정에서 선언문을 실행하여 렉시컬 환경의 환경 레코드에 등록한다. 이후 코드가 실행되면서 함수가 호출되면, 전역 코드의 실행이 중단되고 함수 코드의 평가 및 실행 단계가 실행된다.
실행이 종료되고 어디에서도 참조되지 않을 경우 GC(Gabage Collector)에 의해 소멸하게 된다. (클로저 예외)
1. 평가
- 실행 컨텍스트 생성
- this 바인딩 -> 아직 안배움
- 변수, 함수 등의 선언문 실행
- 렉시컬 환경에 식별자 바인딩
2. 실행
함수의 평가는 실행이 될 때 평가가 된다.
- 코드 순차 실행(인터프리터)
- 실행 컨텍스트에 실행 결과 반영
🤔 argument 와 parameter
argument는 값 자체, parameter는 변수 자체
예를 들어 url 이 있을 때 파라미터는 뭐야? 할 경우 id =1이 있을 경우, Id를 의미하는 것이고 argument는 1을 의미한다 .
📌 실행 컨텍스트의 종류
- Global Execution Context
- Functional Execution Context
- Eval Function Execution Context
- Execution Context Stack (cf. CallStack)
- Global Object
- Global Enviroment Record
- Object Record : Funtion Declaration, Global Object
- Declarative Environment Record
- GlobalThis Value : Global Object를 가르킨다.
- OuterEnv - null
- Function Declaration (함수 선언부)
- Function Object
- Environment : 이 함수가 선언된 EnvRecord
- arguments, length, name ect
- FormalParameter(arguments)
- ESMAScriptCode - AST(Parse Tree의 Root Node)
- This Mode: lexical, strict or Global
- Bound Function Object
- BoundTargetFunction : Function Object를 가르킨다.
- BoundThis : this로 사용될 Object
- Bound Argument, Call(apply, call)
- Function Object
- Function Environment Record
- Function Object : Function Object를 가르킴
- New Target : new.target
- ThisValue : Bind 된 Object || Global Object
- OuterEnv : 이 함수를 호출한 상위 스코프의 EnvRec
배운점
코드가 어떻게 실행되는지 아는게 중요하다, 난 감자다. 완벽하게 정리하다간 하루가 다 지난다... 대충 내가 알아볼 만큼만 정리하기
아직 정리 안한 부분들 - 곧 쓸 예정
Declarative Environment Record : let, const -> 훨씬 빠르다.
FunctionEnvironmentRecord 는 FunctionObject 가 생성이 되었을 때 쓰이는 변수 테이블 ( Var Names )
Object (Environment) Record :
참고
https://velog.io/@jojeon4515/JavaScript-%EC%8A%A4%EC%BD%94%ED%94%84Scope%EB%9E%80
https://weezip.treefeely.com/post/javascript-scope-and-lexical-environment-and-execution-context
'JavaScript' 카테고리의 다른 글
[JS] 클로저 & 커링 (1) | 2025.04.09 |
---|---|
[JS] 메모이제이션 (0) | 2025.04.09 |
[JS] Strict Mode (0) | 2025.04.08 |
[JS] 디스트럭처링(Destructuring) (0) | 2025.04.08 |
[JS] 호이스팅 (0) | 2025.04.07 |