클로저는 이를 지원하지 않는 언어를 사용하다 넘어온 프로그래머에 게는 친근하지 않은 개념일 수 있지만 크롤저를 마스터하기 위한 노력은 분명 도움이 될것이다.
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는 전혀 다른 값을 공유한다.