자바스크립트 - 클로저
안녕하세요, 미래의 코딩 슈퍼스타들! ? 오늘 우리는 자바스크립트 클로저의 세계에 흥미로운 여정을 떠납니다. 그 이름이 조금 무서워 보일 수 있지만 걱정 마세요 - 이 튜토리얼이 끝나면 당신은 클로저의 전문가가 될 것입니다! 좋아하는 음료를 한 잔 마시고 편안하게 앉아 따라와 보세요!
클로저는 무엇인가요?
마법의 상자를 생각해 보세요. 그 안에 들은 모든 것을 기억하는 상자예요. 자바스크립트에서 클로저는 바로 그런 것입니다!
클로저는 외부(포함된) 렉시컬 스코프의 변수에 접근할 수 있는 함수로, 외부 함수가 반환된 후에도 그 값을 기억합니다. 마치 함수가 필요할 때마다 사용할 수 있는 작은 배낭을 메고 다니는 것 같아요.
간단한 예를 보겠습니다:
function outerFunction(x) {
let y = 10;
function innerFunction() {
console.log(x + y);
}
return innerFunction;
}
let closure = outerFunction(5);
closure(); // 출력: 15
이 예제에서 innerFunction
은 클로저입니다. outerFunction
이 실행이 끝난 후에도 x
와 y
의 값을 기억합니다.
렉시컬 스코핑
클로저에 더 깊이 다기 전에 렉시컬 스코핑을 이해해야 합니다. 이 이름은 복잡해 보이지만, 단순히 함수가 외부 스코프의 변수에 접근할 수 있다는 것을 의미합니다.
let name = "Alice";
function greet() {
console.log("Hello, " + name + "!");
}
greet(); // 출력: Hello, Alice!
이 예제에서 greet
는 name
변수에 접근할 수 있어서 렉시컬 스코핑 덕분입니다. 마치 greet
가 주변 환경을 볼 수 있는 것처럼요.
중첩 함수
클로저는 종종 중첩 함수와 관련이 있습니다. 예제를 보겠습니다:
function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}
let counter = outer();
counter(); // 출력: 1
counter(); // 출력: 2
이 예제에서 inner
는 outer
안에 중첩되어 있습니다. 마법이 일어나는 이유는 inner
가 외부 스코프의 count
변수를 기억하기 때문입니다.
반환 함수
자바스크립트의 멋진 점 중 하나는 함수가 다른 함수를 반환할 수 있다는 점입니다. 이는 클로저의 중요한 측면입니다.
function multiplier(x) {
return function(y) {
return x * y;
};
}
let double = multiplier(2);
console.log(double(5)); // 출력: 10
console.log(double(3)); // 출력: 6
이 예제에서 multiplier
는 x
의 값을 기억하는 함수를 반환합니다. 이 반환된 함수는 클로저입니다.
카운터의 딜레마
클로저가 해결할 수 있는 일반적인 문제를 보겠습니다:
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}
let counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // 출력: 2
이 예제에서 클로저는 우리에게 사적인 변수(count
)를 만들어주며, 제공된 메서드를 통해만 접근할 수 있습니다.
예제: 자바스크립트 클로저
우리는 이해를 더욱 확고히하기 위해 더 복잡한 예제를 보겠습니다:
function makeAdder(x) {
return function(y) {
return x + y;
};
}
let add5 = makeAdder(5);
let add10 = makeAdder(10);
console.log(add5(2)); // 출력: 7
console.log(add10(2)); // 출력: 12
이 예제에서 makeAdder
는 x
의 값을 기억하는 클로저를 생성합니다. 다양한 사전 설정된 값을 가진 여러 가지 추가 함수를 만들 수 있습니다.
예제
클로저의 또 다른 실용적인 예제를 보겠습니다:
function createGreeter(greeting) {
return function(name) {
console.log(greeting + ", " + name + "!");
};
}
let greetHello = createGreeter("Hello");
let greetHi = createGreeter("Hi");
greetHello("Alice"); // 출력: Hello, Alice!
greetHi("Bob"); // 출력: Hi, Bob!
이 예제는 클로저를 사용하여 맞춤형 함수를 만드는 방법을 보여줍니다.
클로저의 이점
클로저는 다음과 같은 몇 가지 이점을 제공합니다:
- 데이터 프라이버시
- 함수 팩토리
- 상태 유지
이를 표로 정리해 보겠습니다:
이점 | 설명 | 예제 |
---|---|---|
데이터 프라이버시 | 클로저는 사적인 변수를 만들 수 있습니다 | function counter() { let count = 0; return { increment: () => ++count, getValue: () => count }; } |
함수 팩토리 | 사전 설정된 매개변수를 가진 함수를 생성합니다 | function multiply(x) { return (y) => x * y; } |
상태 유지 | 함수 호출 간 데이터를 유지합니다 | function createGame() { let score = 0; return { addPoint: () => ++score, getScore: () => score }; } |
그렇게 해서 우리는 클로저의 세계를 여행했습니다. 기본부터 고급 개념까지! 기억하시기 바랍니다, 클로저를 마스터하려면 연습이 필요합니다. 즉시 이해가 되지 않는다면 낙담하지 마세요 - 계속 코딩하고 실험을 해보세요, 그러면 곧 클로저의 힘을 제대로 활용할 수 있을 것입니다! ?♂️✨
Credits: Image by storyset