JS는 어휘적 환경을 갖는다.
코드가 위 → 아래 까지 어떻게 동작하는지 파악
코드가 실행되면
스크립트 내에서 선언한 변수들이 어휘적 환경 (Lexical Environment)
에 올라감
let
으로 선언된 변수let one
을 만남.
one
아직 할당 안되어 있음. → 초기값 undefined
를 가짐 → 사용 가능
one
에 1이 할당됨
- 순간, 새로운
어휘적 환경 (Lexical Environment)
생성
이 곳에 저장되는 것
함수가 넘겨받은 매개변수 & 지역 변수들
- 함수가 호출되는 동안, 2개의
Lexical 환경
을 가짐.
내부 Lexical 환경
(함수에서 만들어진)
외부 Lexical 환경
에 대한 참조를 가짐.
현재, 이 함수의 외부 Lexical 환경
은 전역 Lexical 환경
전역 Lexical 환경
(외부에서 받은)
코드에서 변수를 찾을 때, 넓히는 범위 순서
내부부터 찾음. 없으면 → 외부, 없으면 → 전역
Lexical 환경
우선 내부 Lexical 환경
에서 찾음 ( one
& num
)
num
은 찾았지만 one
이 없음
외부로 넓혀서 있는지 찾음
찾음 → 더해줌
function makeAdder(x){
return function(y){
return x + y
}
}
const add3 = makeAdder(3)
console.log(add3(2))
makeAdder
: add
함수를 만들어주는 함수
makeAdder
함수 & 변수add3
:전역 Lexical 환경
에 들어감.
add3
makeAdder
실행 & makeAdder Lexical 환경
만들어짐
Lexical 환경
에 저장되는 것 넘겨받은 매개변수 & 지역 변수들add3
(전역 Lexical 환경
에 있던)
이 함수가 실행되었으니, return
하는 함수가 됨.
add3
을 실행하면 (익명)함수가 실행되는데 이 때 또 Lexical 환경
이 만들어짐.
이번엔 y가 2로 들어감
x+y 하기
처음에는 익명함수 Lexical 환경
에서 x와 y를 찾음
y는 있는데 x는 없음
참조하는 외부 Lexical 환경
(makeAdder
) 으로 감
x를 찾음
Closure
이런 것을 Closure라고 함.
Closure는 함수와 그 함수의 렉시컬 환경의 조합이다.
함수가 생성될 당시의 외부 변수를 기억하고 생성된 이후에도 그 변수에 계속 해서 접근이 가능한 기능인 것
외부 함수의 실행이 끝나서 외부 함수가 소멸된 이후에도 내부 함수가 외부 함수의 변수에 접근 가능
makeAdder(10)
이 호출되지만, add3
에는 변화 없음.
⇒ add10
과 add3
은 서로 다른 환경을 가지고 있는 것
function makeCounter() {
let num = 0; // 외부 함수의 변수. 은닉화.
return function() { // 익명 함수
return num++
}
}
const counter = makeCounter();
console.log(counter()) // 0
console.log(counter()) // 1
console.log(counter()) // 2
counter
에 익명함수(makeCounter
가 리턴하는 함수)를 넣음.
익명함수는 숫자(외부 함수의 변수) 반환
실행 시
초기값 0. 한 번 더하면 1이 증가한 1, 2 이 나옴
내부 함수에서 외부함수의 변수(num
)에 접근한 것
생성(const counter = makeCounter();
)된 이후에 계속 기억하고 있다는 것.
숫자들 (0, 1, 2) 수정
불가능
은닉화 성공
오직 counter를 증가시키고 반환받기 때문에.
갑자기 99로 바꾸기 or 100씩 증가시키기 → 불가능
참고