렉시컬 환경이란? https://leesoo7595.github.io/javascript/2020/07/04/JavaScript_es6_scope/
아래 코드를 예로 들어보면서 차례로 살펴보자.
스크립트 내에서 선언한 변수들이 Lexical 환경에 올라간다.
one : //초기화 안된 상태. 따라서 사용 불가
addOne : function //함수 선언문은 바로 초기화 된다. 사용 가능 (변수에 할당한 함수표현식은 불가능)
let one; // 여기오면 할당은 아니기 때문에 undefined 를 가진다. 사용 가능.
one = 1; // 이제 1이 할당 되었다. one : 1
function addOne(num){ // 함수 선언은 초기에 이미 완료 되었다. 다음으로 넘어간다.
console.log(one + num);
}
addOne(5);
함수가 실행된다. 이때 새로운 Lexical 환경이 만들어진다.
이곳에는 함수가 넘겨받은 매개변수와 지역변수가 저장된다.
함수가 호출되는 동안 다음 두개의 환경을 가진다.
전역 Lexical 환경{
one : 1
addOne : function
}
내부 Lexical 환경 {
num : 5
}
내부 Lexical 환경은 외부 Lexical 환경에 대한 참조를 가진다. 현재 코드에서는
addOne 의 외부 Lexical은 전역 Lexical 환경이다.
코드에서 변수를 찾을 때 내부 Lexical 환경에 없다면 외부 Lexical 에서, 거기도 없으면 전역 Lexical 환경에서 찾는다.
addOne 에서 one 과 num 을 찾는다. num 은 찾았지만 one 이 없다. 외부로 눈을 돌려보니 one 에 1이 할당 되어있는 것을 찾은 것이다.
function makeAdder(x) {
return function(y) {
return x + y;
}
}
const add3 = makeAdder(3);
console.log(add3(2)); // 5. add3 함수가 생성된 이후에도 상위함수인 makeAdder 의 x에 접근 가능
const add10 = makeAdder(10);
console.log(add10(5)); // 15.
console.log(add3(1)); // 4
오직 x + y를 반환 할 뿐이다. 수정 할 수 없다. 이를 은닉화 라고 한다.
Closure
외부 변수를 기억하고 접근할 수 있는 함수를 의미한다.
함수와 렉시컬 환경의 조합이다.
함수가 생성될 당시의 외부 변수를 기억한다.
생성 이후에도 계속 접근이 가능하다! 위의 예제에서 add3이 makeAdder 의 변수를 기억하고 있다.
Lexical 환경
코드가 실행되는 순간 전역 렉시컬 환경이 만들어진다. 그리고 그 안에 함수가 호출 되는 경우에 호출중인 함수를
위한 내부 렉시컬 환경이 또 만들어진다. 그리고 내부 렉시컬 환경은 외부 렉시컬 환경에 대한 참조를 가질 수 있다.
함수가 호출 될 때마다 새로운 렉시컬 환경이 만들어진다. 그리고 ~내부 렉시컬 환경에서 함수를 리턴하는 방식을
중첩 함수라고 한다. 함수는 Environment 라는 숨김 프로퍼티를 가진다. 여기서 함수가 만들어진 곳의 렉시컬
환경에 대한 참조가 저장된다.