화살표를 사용하여 간단한 함수를 만들 수 있다
//1번
const add = (x, y) => x + y;
add(5,7); //12
-----------------------------------------
//2번
const adder = x => y => x + y ;
adder(5)(7); //12
adder(5) // y => x + y
typeof adder(5) // 'function'
------------------------------------------
//3번
const addermore = function (x) { //x가 선언된 외부함수
return function (y){ //y가 선언된 내부함수
return x + y ;
}
}
위 세 개의 함수는 모두 같은 식을 의미한다
두번째와 세번째 코드를 보면 리턴값이 함수임을 알 수 있다
함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합
클로저의 가장 큰 특징은 함수를 두번 리턴하는 함수라는 것
클로저는 리턴하는 함수에 의해 스코프가 구분되는데
핵심은 스코프를 이용해서 변수의 접근 범위를 닫는 것에 있다
const addermore = function (x) { //x가 선언된 외부함수
return function (y){ //y가 선언된 내부함수
return x + y ;
}
}
클로저는 외부 함수의 실행이 끝나더라도, 외부 함수 내 변수가 메모리 상에 저장된다
const addagain = function (x){
return function (y){
return x + y ;
}
}
const add5 = addagain(5);
add5(7) //addagain(5)(7) === 12
add5(10) //addagain(5)(10) === 15
이때 add5에는 addagain함수에 있는 x에 5를 인자로 넘긴 값을 계속 저장한 채로 있음을 확인할 수 있다
이러한 특징은 다음과 같은 유용한 점을 발견할 수 있다
const htmlMaker = tag => textContent => `<${tag}>${textContent}</${tag}>`
htmlMaker('div')('hi'); //(`<${'div'}>${'hi'}</${'div'}>`)
const divmaker = htmlMaker('div');
이렇게 div를 할당해두면 이후 div 영역을 만들 때 언제든지 다시 꺼내어 사용할 수 있다
(그렇다면 빈 html 문서 안에 자바스크립트 만으로 웹을 만들 수 있는 걸까?)
let addnum = function(x) {
let sum = function(y) {
return x + y;
}
return sum;
}
let foo = addnum(1);
foo(3);
let total = foo(6); //7
let foo에 add(1)을 할당했을 때 x에 1의 값이 넘어간 채로 저장된다
foo(6)의 값을 도출할 때 내부함수에는 x의 값이 없기때문에
외부의 x를 참조해서 결과를 도출한다
이때 외부함수라는 '함수의 환경'을 참조하기 때문에 클로저의 특징을 확인할 수 있음
앞서 클로저를함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합
이라고 했는데,
내부함수가 선언되었을 때 내부함수에 필요한 인자(위의 예시에서는 x)를 외부 함수(외부의 환경)에서 주워와서 사용하고 있다는 점에서 그 의미를 약간이나마 이해할 수 있었다
let ageCounter1 = {
age: 20,
increase: function() {
this.age++;
},
decrease: function() {
this.age--;
},
getAge: function(){
return this.age;
}
}
ageCounter1.increase();
ageCounter1.getAge(); // 21
function makeAgeCounter() {
let age = 20;
return {
increase: function() {
age++;
},
decrease: function() {
age--;
},
getAge: function() {
return age;
}
}
}
let ageCounter1 = makeAgeCounter();
ageCounter1.decrease();
ageCounter1.getAge(); // 19
let ageCounter2 = makeAgeCounter();
ageCounter2.increase();
ageCounter2.increase();
클로저 모듈 패턴은 어떤 기능을 하는 함수를 변수에 할당하여 재사용을 가능하게 해줌