함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는 정적 스코프를 의미한다.
생명 주기가 종료된 외부 함수의 변수를 참조하는 중첩 함수를 클로저라고 한다.
함수가 일급 객체이며, 렉시컬 스코프를 따르기 때문이다.
React의 useState
는 setState
를 통해서만 상태를 변경할 수 있다. useState
수명 주기가 끝난 후에 setState
로 상태에 접근하고 변경할 수 있으므로 클로저를 기반으로 구현되어 있을 것이라고 짐작할 수 있다.
function useState(initialValue) {
let state = initialValue;
const getState = () => state;
const setState = (newValue) => {
state = newValue;
};
return [getState, setState];
}
컴포넌트가 렌더링된 후 실행되는 useEffect
의 클린업 함수는 함수가 정의됐을 당시에 상태 값을 참조한다. 이를 통해 클린업 함수가 클로저임을 알 수 있다.
setTimeout의 콜백 함수 혹은 이벤트 핸들러가 외부 데이터를 사용할 때 유용하다.
function outerFunction() {
let message = 'Hello, world!';
setTimeout(function innerFunction() {
console.log(message);
}, 1000);
}
outerFunction();
함수에 일부 인자를 미리 전달하여 함수를 반환하는 경우에 사용할 수 있다.
const debounce = function(func, wait) {
let timeoutId = null;
return function (event) {
const self = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(func.bind(self, event), wait);
};
}
const moveHandler = function(e) {
console.log('move event 처리');
};
document.body.addEventListener('mousemove', debounce(moveHandler, 500));
const wrap = (fn) => {
return function() {
const res = fn.apply(this, arguments);
window.ReactNativeWebView.postMessage('navigationStateChange');
return res;
}
}
history.pushState = wrap(history.pushState);
history.replaceState = wrap(history.replaceState);
history.pushState = function() {
const res = history.pushState.apply(this, arguments);
window.ReactNativeWebView.postMessage('navigationStateChange');
return res;
};
history.replaceState = function() {
const res = history.pushState.apply(this, arguments);
window.ReactNativeWebView.postMessage('navigationStateChange');
return res;
};