클로저의 활용
by 배부른코딩로그클로저라는 개념 뽀개봅시당...!!
대표적으로 DOM의 addEventListener를 예시로 들 수 있습니다.
아무 생각없이 아래와 같이 사용하고 있었으며, 이 예제가 어떤 방식으로 클로저를 사용한 것인지 파악해보시죠 :)
var fruits = ["apple", "banana", "grape"]
var $ul = document.createElement('ul')
var alertFruitBuilder = function(fruit) { // 고차함수
return function() {
alert("Choosed! '" + fruit + "'");
}
}
fruits.forEach(function(fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruitBuilder(fruit));
$ul.appendChild($li);
});
document.body.append($ul)
위 예제에서 주의깊게 보실 부분은 전역변수 'fruits'와 'alertFruitBuilder', 'addEventListener' 입니다.
addEventListener(eventType, callbackFunction) 으로 사용되었습니다.
그러면 callbackFunction인 alertFruitBuilder는 왜 고차함수로 만들어졌을까요?
이유는 간단합니다. callbackFunction의 파라미터로 this값이 전달되어 fruit가 mouse event가 됩니다 ㅎㅎ..
그래서 고차함수를 통해 fruit로 치환된 alert function을 return 한 것이죠.
이 방식으로 alertFruitBuilder의 파라미터 fruit는 참조될 수 있는 가능성을 가지게 되고, 이게 클로저를 활용한 것입니다.
한번 console을 통해서 돌려보시면 이해에 도움이 되실 겁니다.
접근 권한 제어(정보은닉)
클로저, 아직도 잘 이해가 안된다. 다시 도전해봅니다.
흔히 접근 권한에는 public / protected / private 가 있습니다.
public은 외부 접근 가능한 것이고, private는 내부에서만 접근 가능하며 외부로 노출되지 않는 것을 의미합니다.
하지만 자바스크립트에는 이러한 권한을 직접 부여하도록 설계되어 있지 않습니다.
다만, 클로저를 이용하면 return을 통해 public한 값과 private한 값을 구분하는 것이 가능합니다.
var createCar = function() {
var fuel = Math.ceil(Math.random() * 10 + 10);
var power = Math.ceil(Math.random() * 3 + 2);
var moved = 0;
var userAction = {
get move() {
return moved;
},
ride: function() {
var km = Math.ceil(Math.random * 6);
var wasteFuel = km / power;
if(fuel < wasteFuel) {
console.log('No fuel!!!');
return;
}
fuel -= wasteFuel;
moved += km;
console.log(km + 'km moved! (Total: ' + moved + 'km). Fuel remaining volume: ' + fuel);
}
};
Object.freeze(userAction);
return userAction;
};
var car1 = createCar();
var car2 = createCar();
var car3 = createCar();
Car 객체 생성을 통해 지역변수인 fuel / power / moved 에 대해 클로저를 적극 활용한 케이스입니다.
createCar()를 통해 객체 생성 후, fuel, power, moved에 대해 기존에 선언된 값을 유지하며 ride 메서드를 수행합니다.
이런 함수형 프로그래밍이 클로저를 적극 활용한 예시입니다.
이런 예시를 보니 조금씩 감이 잡히는 것 같습니다 :)
아마도...?!
커링 함수(currying function)
커링함수란, 여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠 순차적으로 호출될 수 있게 체인 형태로 구성한 것을 말합니다
주요 포인트는 커링은 한 번에 하나의 인자만 전달하는 것이 원칙입니다.
var curry1 = function(func) {
return function(a) {
return function(b) {
return func(a, b);
}
}
}
var getMaxWithNum = curry1(Math.max)(10);
console.log(getMaxWithNum(9)); // 10
console.log(getMaxWithNum(15)); // 15
console.log(getMaxWithNum(2)); // 10
var curry2 = function(func) {
return function(a) {
return function(b) {
return function(c) {
return function(d) {
return func(a, b, c, d);
}
}
}
}
}
var curry2_ = func=> a=> b=> c=> d=> func(a,b,c,d);
console.log(curry2(Math.min)(5)(1)(8)(6)); // 1
console.log(curry2_(Math.min)(5)(2)(7)(3)); // 2
커링함수는 상당히 유용합니다.
당장 필요한 정보만 받아서 전달하고 또 다시 필요한 정보가 들어오면 전달하는 방식입니다.
그리고, 결국 마지막 인자가 넘어갈 때까지 함수의 실행이 미뤄집니다.
이를 함수형 프로그래밍에서 '지연 실행(lazy execution)' 이라고 부릅니다.
즉, 함수의 실행을 원하는 시점까지 지연시켰다가 실행하고 싶은 상황에서 커링 함수는 유용합니다.
서버와의 통신 프로그래밍에서 커링이 사용된 예시입니다.
위 예제와 같이 한번 만들어두면 유용하게 사용할 수 있는 커링함수가 만들어졌습니다 : )
var getUrl = function(baseUrl) {
return function(path) {
return function(id) {
return baseUrl + path + id;
}
}
}
var getRequestURL = getUrl('http://localhost:8080')('/js'); // 미리 값 선언
console.log(getRequestURL('/currying')); // http://localhost:8080/js/currying
만약, 틀렸다면 댓글로 가르침 감사하겠습니다!
[출처] '코어 자바스크립트 - 핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍', 정재남 지음
'자바스크립트 > 코어 자바스크립트' 카테고리의 다른 글
클래스(Class) (0) | 2020.04.23 |
---|---|
클로저(Closure) (0) | 2020.04.05 |
콜백 함수(Callback function) (0) | 2020.03.31 |
this (0) | 2020.03.28 |
메모리와 데이터 (0) | 2020.03.21 |
블로그의 정보
배부른코딩로그
배부른코딩로그