어려운 내용이라 두서없이 서술되어있습니다.
실행할 코드에 제공할 환경 정보들을 모아놓은 객체
- 최초 시동시 콜스택에 전역컨텍스트가 쌓이며 그이후 함수를 호출할때마다 해당 컨텍스트가 콜스택에 쌓이는 형태
종류
- VariableEnvironment: 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보.
선언 시점의 LexicalEnvironment의 스냅샷snapshot으로, 변경 사항은 반영되지 않음. - LexicalEnvironment: 처음에는 VariableEnvironment와 같지만 변경 사항이 실시간으로 반영됨.
- ThisBinding: this 식별자가 바라봐야 할 대상 객체.
정리 먼저하기
- 실행 컨텍 스트는 전역 공간에서 자동으로 생성되는 전역 컨텍스트와 eval 및 함수 실행에 의한 컨 텍스트 등이 있습니다
- 활성화되는 시점에 VariableEnvironment, LexicalEnvironment, ThisBinding의 세 가지 정보를 수집합니다
- 실행 컨텍스트를 생성할 때는 VariableEnvironment와 LexicalEnvironment가 동일한 내 용으로 구성되만
LexicalEnvironment는 함수 실행 도중에 변경되는 사항이 즉시 반 영되는 반면 VariableEnvironment는 초기 상태를 유지합니다 - LexicalEnvironment는 매개변수명, 변수의 식별자, 선언한 함수의 함수명 등을 수집 하는 environmentRecord와
바로 직전 컨텍스트의 LexicalEnvironment 정보를 참조하는 outerEnvironmentReference로 구성돼 있습니다
VariableEnvironment
LexicalEnvironment와 같지만 최초실행시의 스냅샷을 담고있습니다.
실행컨텍스트를 생성할때 VariableEnvironment에 정보를 수집 후 카피하여 LexicalEnvironment에 담은 후
LexicalEnvironment를 사용합니다.
구성
environmentRecord
outer-evnironmentRefernce
LexicalEnvironment
사전에는 정적환경, 혹은 어휘적환경 이라고 직역되지만
해당 사전적환경 참고할수있는 서적등으로 제가 보는책에서는 비유하고있습니다.
environmentRecord와 호이스팅
함수선언문(함수 내부가 아닌 함수선언문 자체), 변수, Parameter로 구성되어있습니다.
위에서 부터 훓으며 레코드를 수집합니다.
호이스팅
끌어올리다는 의미로 변수 수집정보를 이해하기 쉽게 가상화된 개념입니다.
실행전 변수들을 먼저 environmentRecord에 담아 놓기때문에 실행순서가 위에있다고 여겨져
끌어올리다 라는 개념이 생겨난 것입니다.
함수 선언문과 함수표현식
- 함수선언문: 함수를 선언 하는 문구
- 함수표현식: 함수를 표현하는 문구
함수 선언문은 기명함수, 함수표현식은 익명함수로써 많이 표현됩니다.
함수선언문은 선언문에 함수이름이 존재하지만 함수표현식은 표현식을 특정 변수에 담는것으로 작동합니다.
이과정에서 나오는 특이점이
호이스팅이 함수선언문은 함수자체를 끌어올리지만, 변수에 함수표현식이 할당된경우에는 단순 변수만 끌어 올립니다.
만약아래와 같은 코드가있다면
function a (x){
return x
}
var b = (x)=>{return x}
아래와같이 변수명만 호이스팅 됩니다.
var a = function a (x){
return x
}
var b
이로인해 나타나는 현상은 아래와 같습니다.
console.log(a(3)) // 3
console.log(b) // undifined
console.log(b()) // b is not a function 에러 발생
function a (x){
return x
}
var b = (x)=>{return x}
다만 선언후에 호출하는것이 자연스러운 인식 이기에 이부분에 대해서는 오히려 익명함수가 더욱 효율적으로 보입니다.
Scope (식별자범위)
Scope란 식별자의 범위를 의미합니다 A함수 내부에 선언된 변수는 외부에서 접근할 수 없고
A함수 외부에서 선언된 변수는 A함수 내부에서는 접근이 가능합니다.
이러한 식별자의 범위를 Scope라고합니다.
이 Scope는 ES5 이전까지는 오직 함수에 의해서만 생성되었습니다.
(ES6에서는 블록으로도 Scope가 생성가능하며 함수스코프와 블록스코프 라는 용어로 구분합니다.)
Scope Chain & outerEnvironmentReference
outerEnvironmentReference은 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조합니다.
참조 즉 연결리스트 형태의 구조를 가지고 있습니다.
연결리스트의 형태이기에 가장가까운 LexicalEnvironment부터 찾아 올라가며 다른순서는 불가능합니다.
또한, 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에만 접근 가능한 특징을 가지고있습니다.
var a = 1
function outer(){
function inner(){
var a = 3
console.log(a) // 3
}
inner()
console.log(a) // 1
}
outer()
inner()는 해당 스코프에서 a = 3 을 선언하였기에 3이 출력됩니다.
outer()는 선언하지 않았지만 전역변수인 a = 1에 따라 1이 출력되게 됩니다.
LexicalEnvironment에서 식별자가 발견되었기때문에 더이상 상위로 검색하지 않으며
다르게 본다면 해당 스코프에서 전역변수를 선언한다면 전역변수에 접근할수 없게됩니다.
이를 변수 은닉화 라고 합니다.
this
thisBinding에는 this로 지정된 객체가 저장됩니다.
실행 컨텍스트 활성 화 당시에 this가 지정되지 않은 경우 this에는 전역 객체가 저장됩니다
'JavaScript > JavaScript' 카테고리의 다른 글
[Javascript] 자바스크립트 이벤트루프 (0) | 2022.11.21 |
---|---|
[Javascript] async & await 비동기처리 (0) | 2022.11.21 |
[JavaScript] Promise & async / await 자바스크립트 비동기처리 (1) | 2022.11.21 |