클로저(Closure)는 함수와 함수가 선언된 어휘적(lexical) 환경의 조합이다. 즉, 함수가 생성될 당시의 외부 변수를 기억하여 생성 이후에도 계속 접근 가능한 것이다.
<script>
let one = 'one';
function fn1() {
let two = 'two';
console.log(one, two); // one two
}
fn1();
</script>
<script>
let one = 'one';
function fn2() {
let three = 'three';
console.log(one, two, three); // two is not defined
}
function fn1() {
let two = 'two';
console.log(one, two); // one two
fn2();
}
fn1();
</script>
즉, 함수는 어디서 실행됐는지가 중요하지 않음
<script>
let one = 'one';
function fn1() {
function fn2() {
let three = 'three';
console.log(one, two, three); // one two three
}
let two = 'two'
console.log(one, two) // one two
fn2();
}
fn1();
</script>
즉, 함수의 유효범위는 함수가 어디서 실행됐는지가 아니라 어디서 정의됐는지에 따라 달라짐
즉, 전역 변수의 사용을 억제해 상태 변경이나 가변 데이터를 피하고 안정성을 증가 시킬 수 있음
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick())
function handleCilck(){
let count = 0
return function(){
count++
return count
}
}
function Hello(name) {
this._name = name;
}
Hello.prototype.say = function() {
console.log('Hello, ' + this._name);
}
let hello1 = new Hello('채린');
let hello2 = new Hello('채채');
let hello3 = new Hello('째째');
hello1.say(); // 'Hello, 채린'
hello2.say(); // 'Hello, 채채'
hello3.say(); // 'Hello, 째째'
hello1._name = 'anonymous';
hello1.say(); // 'Hello, anonymous'
이렇게 하게되면 외부에서 쉽게 접근 가능하게 됨
function hello(name) {
var _name = name;
return function() {
console.log('Hello, ' + _name);
};
}
let hello1 = hello('채린');
let hello2 = hello('채채');
let hello3 = hello('째째');
hello1(); // 'Hello, 채린'
hello2(); // 'Hello, 채채'
hello3(); // 'Hello, 째째'
<!DOCTYPE html>
<html>
<body>
<button class="toggle">toggle</button>
<div class="box" style="width: 100px; height: 100px; background: red;"></div>
<script>
var box = document.querySelector('.box');
var toggleBtn = document.querySelector('.toggle');
var toggle = (function () {
var isShow = false;
// ① 클로저를 반환
return function () {
box.style.display = isShow ? 'block' : 'none';
// ③ 상태 변경
isShow = !isShow;
};
})();
// ② 이벤트 프로퍼티에 클로저를 할당
toggleBtn.onclick = toggle;
</script>
</body>
</html>
클로저를 사용하면 매번 새로운 함수가 리턴되어 같은 기능을 함수가 다른 메모리 공간을 차지한다고 보면 된다. 그렇기 때문에 성능 측면을 고려했을 때 꼭 필요한 경우가 아니라면 클로저를 사용하지 않는 것이 좋다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
https://www.youtube.com/watch?v=bwwaSwf7vkE&t=133s
https://devkingdom.tistory.com/331
https://hyunseob.github.io/2016/08/30/javascript-closure/
Image by Mohammad Sheyriyar Shah from Pixabay