동기들에게 클로저를 쉽게 설명하기 위해서 설명했던 자료이다
어려운 단어들은 최대한 배제하고 설명하였다.
클로저를 설명하려면 여러가지 배경 지식들이 있어야한다
이런 내용들을 모두 설명하려면 초보자들(나도 포함)은 이해를 못하기 쉽상이다
들어가기 전에 호이스팅과 변수 정도는 공부를 해야한다
그럼 시작해보자
우리가 코드가 호이스팅 되서 변수가 변화하는 과정을 명시적으로, 즉 눈에 보이게 할 수는 없다
이는 컴퓨터 내부에서 나타나는 변화이기 때문이다
우리가 언어적으로만 표현할 수 있는 환경 그래서 렉시컬(언어적) 환경이라고 칭한다
컴퓨터는 자바스크립트 코드가 실행되면 전체 코드를 스캔한다(유식한 말로는 파싱한다)
스캔 후 함수와 변수를 스캔 해서 실행 컨텍스트에 호이스팅 한다
나는 실행 컨텍스트를 변수와 함수가 입주하는 아파트 라고 칭한다
이제부터 실행컨텍스트와 코드 칸을 나눠서 작성 해보겠다
3층 301호(3층 렉시컬 환경) y=3(매개변수)
2층 201호(2층 렉시컬 환경) x=3(매개변수)(2에서 삭제)
1층 101호(1층 렉시컬 환경) add : 변수 -> 2에서 함수가 담긴다, makeAdder : f
function makeAdder(x){ // 1
return function(y){ // 2
return x + y; // 3
}
}
const add3 = makeAdder(3); // 4
console.log(add3(2)); // 5
=> 이때 실행컨텍스트에 없지만 값을 참조하는 내부함수를 클로저라고 한다
=> 같은 말이지만 내부함수의 렉시컬 환경이 외부보다 오래 살아있으면 클로저라고 한다
let num = 0;
function addNum(){
return num++;
};
let counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
원리는 위와 같기 때문에 장황하게 설명하지 않겠다
만약 이런 코드를 짰다고 생각해보자
나는 콘솔을 찍을 때 마다 0, 1, 2가 차례로 나오게 하고 싶은것이다
let num = 0;
function addNum(){
return num++;
};
// 1억개의 코드
num = 100;
// 1억개의 코드
let counter = makeCounter();
console.log(counter()); // 0 -> 100
console.log(counter()); // 1 -> 101
console.log(counter()); // 2 -> 102
사이에 수많은 코드가 있는데 누가 중간에 재할당을 했다고 가정해보자
엥
100부터 시작하게 되어버린다
만약 이것이 이해가 안된다면 호이스팅을 더 공부해야한다
만약 결과는 무조건 0부터 시작해서 1씩 증가해야한다면 나는 let num 이라는 변수를 보호할 필요가 있다
var까지 참조를 막아줄 수 있는 스코프는 함수 스코프이다
이해가 안간다면 변수와 스코프를 공부 해야한다
function makeCounter() { let num = 0;
return function(){
return num++;
};
}
let counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
이렇게 함수로 싸서 보호를 해준다면 완벽히 참조가 불가능 할것이다.
남들도 봤을때 클로저구나 이건 값이 바뀌면 안된다고 생각할 수 있다.
또한 지역변수로 변수를 선언했기 때문에 이 변수는 안전하다
여러 이점이 있기 때문에 꼭 알아둬야한다
추가로 회사마다 다르긴 하지만 IIFE패턴을 쓰는 회사는 클로저로 함수 보호를 하기때문에 알아둬야한다
하지만 요즘은 모듈화를 더 추구하는 분위기이다