자신을 내포하는 함수의 컨텍스트에 접근할 수 있는 함수
- 더글라스 크록포드, 《자바스크립트 핵심 가이드), 한빛미디어(p68)
함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 것
- 에단 브라운, 《러닝 자바스크립트》, 한빛미디어 (p196)
함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 있는 함수
- 존 레식, 《자바스크립 트 닌자 비급》, 인사이트(p116)
이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 함수
- 송형주 고현준, 《인사이드 자바스크립 트), 한빛미디어(p157)
자유변수가 있는 함수와 자유변수를 알 수 있는 환경의 결합
- 에릭 프리먼, <Head First Javascript Programming》, 한빛미디어(p534)
→ 정리: “어떤 함수에서 선언한 변수를 참조하는 내부함수에서 발생하는 현상”
let outer = function () {
let a = 1;
let inner = function () {
console.log(++a);
}
inner();
}
outer();
let outer = function () {
let a = 1;
let inner = function () {
console.log(++a);
}
return inner;
}
const inner = outer();
inner(); // 2
inner(); // 3
(function () {
var count = 0;
var button = document.createElement('button');
button.innerText = 'click';
var clickHandler = function () {
console.log(++count, 'times clicked');
if (count >= 10) {
button.removeEventListener("click", clickHandler);
clickHandler = null; // clickHandler 식별자의 함수 참조를 끊음
}
};
button.addEventListener('click', clickHandler);
document.body.appendChild(button);
})();
var fruits = ['apple', 'banana', 'peach'];
var $ul = document.createElement('ul');
fruits.forEach(function (fruit) { // A
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', function () { // B
console.log('your choice is ' + fruit);
})
$ul.appendChild($li);
})
document.body.appendChild($ul)
[object MouseEvent]
)를 주입한다. var fruits = ['apple', 'banana', 'peach'];
var $ul = document.createElement('ul');
var consoleFruit = function (fruit) {
return function () { // [object MouseEvent] 첫번째 인자로 주입.
console.log('your choice is ' + fruit);
}
}
fruits.forEach(function (fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', consoleFruit(fruit))
$ul.appendChild($li);
})
document.body.appendChild($ul)
ES5 기준으로는 아직 private class field(#)가 도입되기 전이다. ES2019에 도입
- 접근 권한에는 public, private, protected 등…
- 클로저를 이용해 public 값과 private 값을 구분하는 것이 가능하다.
var outer = function (){
var a = 1;
var inner = function () {
return ++a;
}
return inner;
}
var outer2 = outer();
console.log(outer2()); // 2
console.log(outer2()); // 3
var add = function () {
var result = 0;
for (var i = 0; i < arguments.length; i++){
result += arguments[i];
}
return result;
}
var addPartial = add.bind(null, 1, 2, 3, 4, 5);
console.log(addPartial(6, 7, 8, 9, 10)); // 55
var partial = function () {
var originalPartialArgs = arguments;
var func = originalPartialArgs[0];
if (typeof func !== 'function') {
throw new Error('첫 번째 인자가 함수가 아닙니다.');
}
return function () {
var partialArgs = Array.prototype.slice.call(originalPartialArgs, 1);
var restArgs = Array.prototype.slice.call(arguments);
return func.apply(this, partialArgs.concat(restArgs));
}
}
var add = function () {
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
};
var addPartial = partial(add, 1, 2, 3, 4, 5);
console.log(addPartial(6, 7, 8, 9, 10)); // 55
var curry3 = function (func) {
return function (a) {
return function (b) {
return func(a, b);
};
}
}
var getMaxWith10 = curry3(Math.max)(10);
console.log(getMaxWith10(8)); // 10
console.log(getMaxWith10(13)); // 13