클로저(closure)는 프로그래머가 창조적이고 인상적이며 간결한 프로그래밍을 할 수 있게 해줍니다.
클로저는 빈번하게 사용되며 자바스크립트 스킬과 관계없이 자주 마주치게 될 것입니다.
물론, 지금 당장 클로저는 복잡해 보일 수 있습니다만, 이 글을 읽고 클로저에 대해 이해하게 된다면 자바스크립트 코딩시에 매일 사용하게 될 것입니다.
이 글은 비교적 클로저에 대해 간략히 설명하고 있습니다. 이 글을 계속 읽기 전에 먼저 자바스크립트 변수 범위에 대해 이해할 필요가 있습니다.
만약 그렇지 못하다면 호이스팅에 관한 지식을 먼저 이해하시고 이 글을 읽어주시기 바랍니다.
function showName(firstName, lastName) {
var nameIntro = "Your name is ";
// 이 내부 함수는 외부함수의 변수뿐만 아니라 파라미터 까지 사용할 수 있습니다.
function makeFullName() {
return nameIntro + firstName + " " + lastName;
}
return makeFullName();
}
showName("Michael", "Jackson"); // Your name is Michael Jackson
클로저는 Node.js의 비동기, 논-블록킹 아키텍처의 핵심기능으로 활용되고 있습니다.
$(function() {
var selections = [];
$(".niners").click(function() { // 이 클로저는 selections 변수에 접근합니다.
selections.push(this.prop("name")); // 외부 함수의 selections 변수를 갱신함
});
});
function celebrityName(firstName) {
var nameIntro = "This is celebrity is ";
// 이 내부 함수는 외부함수의 변수와 파라미터에 접근할 수 있습니다.
function lastName(theLastName) {
return nameIntro + firstName + " " + theLastName;
}
return lastName;
}
var mjName = celebrityName("Michael"); // 여기서 celebrityName 외부함수가 리턴됩니다.
// 외부함수가 위에서 리턴된 후에, 클로저(lastName)가 호출됩니다.
// 아직, 클로저는 외부함수의 변수와 파라미터에 접근 가능합니다.
mjName("Jackson"); // This celebrity is Michael Jackson
클로저는 외부 함수의 변수에 대한 참조를 저장합니다.
function celebrityID() {
var celebrityID = 999;
// 우리는 몇개의 내부 함수를 가진 객체를 리턴할것입니다.
// 모든 내부함수는 외부변수에 접근할 수 있습니다.
return {
getID: function() {
// 이 내부함수는 갱신된 celebrityID변수를 리턴합니다.
// 이것은 changeThdID함수가 값을 변경한 이후에도 celebrityID의 현재값을 리턴합니다.
return celebrityID;
},
setID: function(theNewID) {
// 이 내부함수는 외부함수의 값을 언제든지 변경할 것입니다.
celebrityID = theNewID;
}
}
}
var mjID = celebrityID(); // 이 시점에, celebrityID외부 함수가 리턴됩니다.
mjID.getID(); // 999
mjID.setID(567); // 외부함수의 변수를 변경합니다.
mjID.getID(); // 567; 변경된 celebrityID변수를 리턴합니다.
function aaa(b) {
var i;
var num = 100;
for (i=0; i<b.length; i++) {
b[i].id = function(){
return num+i;
};
}
return b;
}
var abcd = [
{name:"LHJ", id:0},
{name:"JJJ", id:0},
{name:"AAA", id:0}
]
var c = aaa(abcd);
console.log(c);
[{…}, {…}, {…}]
0: {name: "LHJ", id: ƒ}
1: {name: "JJJ", id: ƒ}
2: {name: "AAA", id: ƒ}
length: 3
__proto__: Array(0)
console.log(c[0]["id"]());
103
위의 예제에서 익명의 내부함수가 실행될 시점에 i의 값은 3입니다. (배열의 크기만큼 증가한 값)
function aaa(b) {
var i;
var num = 100;
for (i=0; i<b.length; i++) {
b[i].id = function(){
return num+i;
}();
}
return b;
}
var abcd = [
{name:"LHJ", id:0},
{name:"JJJ", id:0},
{name:"AAA", id:0}
]
var c = aaa(abcd);
console.log(c);
(3) [{…}, {…}, {…}]
0: {name: "LHJ", id: 100}
1: {name: "JJJ", id: 101}
2: {name: "AAA", id: 102}
length: 3
__proto__: Array(0)