클로저
Closure
어휘적 환경(Lexical Environment)
어떻게 동작하는지
// 코드가 실행되면 스크립트 내에서 선언한 변수들이 Lexical 환경에 올라간다.
// Lexical 환경 - one: 초기화 x / addOne: function
let one; // Lexical 환경 - one: undefined(사용해도 에러는 안남) / addOne: function
one = 1; // Lexical 환경 - one: 1 / addOne: function
addOne(9); // 전역 Lexical 환경 - one: 1 / addOne: function // 새로운 내부 Lexical 환경 - num: 9
function addOne(num) {
console.log(one + num);
}
addOne(5); // 전역 Lexical 환경 - one: 1 / addOne: function // 새로운 내부 Lexical 환경 - num: 5
내부 Lexical 환경은 외부 Lexical 환경에 대한 참조를 받는다.
코드에서 변수를 찾을 때 내부 -> 외부 -> 전역의 순서로 찾는다.
function makeAdder(x) { // 전역 Lexical 환경 - makeAdder: function / add3: 초기화x
return function(y) {
return x + y;
}
}
const add3 = makeAdder(3); // 전역 Lexical 환경 - makeAdder: function / add3: function // makeAdder Lexical 환경 - x: 3
console.log(add3(2)); // 전역 Lexical 환경 - makeAdder: function / add3: function // makeAdder Lexical 환경 - x: 3 // 익명함수 Lexical 환경 y : 2
함수의 Lexical 환경(makeAdder Lexical 환경)에는 넘겨받은 매개변수(x: 3)와 지역변수들이 저장된다.
익명함수 -> makeAdder -> 전역 순서로 변수를 찾는다.
- function(y)은 자신이 y를 가지고 있고 상위함수인 makeAdder의 x에 접근 가능
- add3 함수가 생성된 이후에도 상위함수의 x에 접근 가능
- 이러한 것을 Closure 이라고 한다. Closure는 함수와 그 함수의 렉시컬 환경의 조합이고, 함수가 생성될 당시의 외부 변수를 기억하고 생성된 이후에도 계속 접근 가능
const add3 = makeAdder(3);
const add10 = makeAdder(10);
console.log(add10(5)); // 15
console.log(add3(1)); // 4
makeAdder(10)이 호출되지만 makeAdder(3)에는 아무런 영향을 미치지 않는다. 서로 다른 환경을 가지고 있기 때문에
예문
function makeCounter(){
let num = 0;
return function(){
return num++
};
}
let counter = makeCounter()
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
내부함수에서 외부함수의 변수인 num에 접근한다.
생성된 이후에 계속 기억한다.
결과로 나온 숫자들은 수정할 수 없다.(은닉화)
댓글남기기