
클로저는 이를 지원하지 않는 언어를 사용하다 넘어온 프로그래머에 게는 친근하지 않은 개념일 수 있지만 크롤저를 마스터하기 위한 노력은 분명 도움이 될것이다.
function makeSandwich(){
var magicIngredient = "peanut butter";
function make(filling){
return magicIngredient + "and"+ filling;
}
return make("jelly");
}
makeSandwich(); //peanut butter and jelly
내부의 make 함수가 바깥에서 선언된, makeSandwich 함수에서 선언된magicIngredient 변수를 참조했다는 사실을 주목해야한다.
자바스크립트는 1급객체이다. 이는 내부함수를 리턴할 수 있고, 이함수가 나중에 다시 호출될 수 있다는 뜻이다.
function snadwichMaker(){
var magicingredient = "peanut butter";
function make(filling){
return magicIngredient + "and"+ filling;
}
return make;
}
var f = sandwichMaker(); //make함수 전달
f("jelly") // "peanut butter and jelly"
f("banana") // "peanut butter and banana"
f("marshmallows") // "peanut butter and marshmallows"
make 함수를 리턴한다는것 말고는 위의 코드와 동일하다. make함수가 return 되어 변수 f에 저장되어있더라도 magicingredient 변수의 값을 기억하고 있다.
이떻게 이런일이 가능할까? 자바스크립 함수는 해당 스코프에서 선언되어 참조할 수 있는 어떤 변수더라도 내부적으로 보관한다. 함수 자신이 포함하는 스코프의 변수들을 추적하는 함수르 클로저라고 한다.
magicingredient 와 filling 두개의 변수가 클로저에 저장되어있기 때문에 참조할 수 있다.
function sandwichMaker(magicIngredient){
function make(filling){
return magicIngredient + " and " + filling;
}
return make;
}
var hamAnd = sandwichMaker("ham");
hamAnd("cheese") // "ham and cheese"
hamAnd("mustard") // "ham and mustard"
var turkeyAnd = sandwichMaker("turkey");
turkeyAnd("Swiss"); // "turekey and Swiss"
turkeyAnd("Provolone"); // "turekey and Provolone"
같은 sandwichMaker 함수에서 나왔지만 다른 magicIngredient 변수를 클로저에 저장해 둔다. 즉 둘은 서로다른 객체이다. 클래스가 서로다른 객체를 만들어 내듯 서로다른 함수를 만들어 내는것 같다.
이처럼 클로저는 많은 유용한 코딩 관례들의 중심이 된다. 클로저를 생성하기 위한 더 편리하고 일반적인 문법을제공하는데, 함수 표현식이 바로 그것이다.
function sandwichMaker(magicingredient){
return function(filling){
return magicIngredient + " and "+ filling;
}
}
이 함수는 지역적으로 호출하기위해 만들어진게 아닌 새로운 함수 값을 만들어 내기위한 용도이기 때문에 이름을 지을 필요가없다.
function box(){
var val = undefined;
return {
set:function(newVal){val = newVal;},
get:function(){return val;},
type:function(newVal){return typeof val;}
}
}
var b = box();
b.type(); // "undefined"
b.set(98.6);
b.get() //98.6
b.type() // "number"
var a = box();
a.get() // undefined.
이 예제는 세개의 클로저 즉 set, get, type 프로퍼티들을 포함하는 객체를 생성한다.
a와 b는 서로다른 객체이기 때문에 영향을 주고 받지 않는다. 내부 클로저 함수들은 모두 같은 값을 공유하지만 a 와 b는 전혀 다른 값을 공유한다.