어휘적 환경(Lexical Environment)
let one;
one = 1;
function addOne(num){
console.log(one + num);
}
addOne(5);
코드가 위에서부터 아래로 어떻게 동작하는지 알아보자.
Lexical 환경 one : 초기화X 사용 불가 addOne : function 사용 가능 |
프로그램이 실행되면 스크립트 내에서 선언한 변수들이 lexical 환경에 올라간다. let으로 선언한 변수는 초기화 되어 있지 않기 때문에 사용할 수 없다. 반면 함수 선언문은 바로 초기화되어 사용할 수 있다. (함수 표현식은 불가능)
let one;
Lexical 환경 one : undefined 사용 가능 addOne : function |
아직 할당은 안 되어 있기 때문에 undefined를 갖는다. 이제 사용해도 에러가 발생하지 않는다.
one = 1;
Lexical 환경 one : 1 addOne : function |
함수 선언문은 초기에 완료되었기 때문에 건너뛴다
addOne(5);
전역 Lexical 환경 one : 1 addOne : function |
↑ 참조
내부 Lexical 환경 num : 5 |
함수가 실행되는 순간 새로운 lexical 환경이 만들어진다. 이 곳에 함수가 넘겨받은 매개변수와 지역 변수들이 저장된다.
내부 lexical 환경은 외부 lexical 환경에 대한 참조를 갖는다. 위 코드에서는 함수의 외부 lexical 환경이 전역 lexical 환경이다. 코드에서 변수를 찾을 때 내부에서 찾고, 없으면 외부, 외부에도 없으면 전역으로 범위를 넓혀서 찾는다.
다른 예시이다.
function makeAdder(x){
return function(y){
return x + y;
}
}
const add3 = makeAdder(3);
console.log(add3(2));
전역 Lexical 환경 makeAdder : function add3 : 초기화X |
최초 실행 시 전역 lexical 환경에 makeAdder과 add3이 들어간다. add3은 초기화 되지 않은 상태이고 사용할 수 없다.
const add3 = makeAdder(3);
전역 Lexical 환경 makeAdder : function add3 : function |
makeAdder Lexical 환경 x : 3 |
이 코드가 실행되는 순간 makeAdder lexical 환경이 생성되고 넘겨 받은 매개변수와 지역 변수들이 저장된다. 전역 lexical 환경의 add3은 함수가 실행되었으니 리턴하는 함수가 된다.
console.log(add3(2));
전역 Lexical 환경 makeAdder : function add3 : function |
↑ 참조
makeAdder Lexical 환경 x : 3 |
↑ 참조
익명함수 Lexical 환경 y : 2 |
add3 함수가 실행되면서 또 lexical 환경이 만들어진다. makeAdder가 리턴하는 함수는 y를 가지고 있고 상위함수인 makeAdder의 x에 접근 가능하다. add3 함수가 생성된 이후에도 makeAdder의 x에 접근 가능하다.
Closure
- 함수와 렉시컬 환경의 조합
- 내부 함수가 생성될 당시의 외부 함수의 변수에 접근할 수 있는 구조
- 생성 이후에도 계속 접근 가능
function makeAdder(x){
return function(y){
return x + y;
}
}
const add3 = makeAdder(3);
console.log(add3(2)); // 5
const add10 = makeAdder(10);
console.log(add10(5)); // 15
console.log(add3(1)); // 4
makeAdder 함수가 호출될 때, x 값은 고정되고 반환된 함수는 이 값을 기억한다.
makeAdder(10)이 호출되지만 add3(1)에는 아무 변화가 없다. add3과 add10은 서로 다른 환경을 가지고 있는 것이다.
'Language > Javascript' 카테고리의 다른 글
[Javascript] call, apply, bind (0) | 2021.12.25 |
---|---|
[Javascript] setTimeout / setInterval (0) | 2021.12.23 |
[Javascript] 나머지 매개변수(Rest parameters), 전개 구문(Spread syntax) (0) | 2021.12.22 |
[Javascript] 구조 분해 할당(Destructuring assignment) (0) | 2021.12.22 |
[Javascript] 배열(Array), 배열 메소드(Array methods) (0) | 2021.12.19 |