클로저
란 어떤 함수A에서 선언한 변수a를 참조하는 내부함수B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수a가 사라지지 않는 현상
고차함수
: 함수를 인자로 받거나 또는 함수를 반환함으로써 작동 하는 함수var fruits = ['apple', 'banana', 'peach'];
var $ul = document.createElement('ul');
var alertFruitBuilder = function (fruit) {
return function () {
alert('your choice is ' + fruit);
}
}
fruits.forEach(function (fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruitBuilder(fruit));
$ul.appendChild($li);
})
document.body.appendChild($ul)
정보은닉
: 어떤 모듈의 내부로직에 대해 외부로의 노출을 최소화해서 모듈간의 결합도를 낮추고 유연성을 높이고자 하는 현대 프로그래밍 언어의 중요한 개념addPartial함수는 인자 5개를 미리 적용하고 추후 추가적으로 인자들을 전달하면 모든 인자를 모아 원래의 함수가 실행되는 부분적용함수
하지만 this의 값을 변경할 수 없기 때문에 메서드에서는 사용할 수 없음
var add = function () {
console.log(this)
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));
var objA = {
name: "a",
addMethod: add
}
var objB = {
name: "b",
addMethod: addPartial
}
// 메서드로서 호출했을 때 this는 함수앞의 객체
console.log(objA.addMethod(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
// 하지만 objB는 addPartial을 addMethod로 넣었기 때문에 -> Window
console.log(objB.addMethod(6, 7, 8, 9, 10))
this에 관여하지 않는 클로저를 사용하는 부분적용함수
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 () {
console.log(this);
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));
var objB = {
name: "b",
addMethod: addPartial
}
console.log(objB.addMethod(6,7,8,9,10));
Object.defineProperty(window, '_', {
value: 'EMPTY_SPACE',
writable: false,
configurable: false,
enumerable: false
})
var partial2 = 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);
for (var i = 0; i < partialArgs.length; i++) {
if (partialArgs[i] === _) {
partialArgs[i] = restArgs.shift(); // 배열의 앞에서 원소를 빼냄
}
}
console.log(partialArgs, restArgs);
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 = partial2(add, 1, 2, _, 4, 5, _, _, 8, 9);
console.log(addPartial(3, 6, 7, 10));
디바운스
: 짧은 시간동안 동일한 이벤트가 많이 발생할 경우 이를 전부 처리하지 않고 처음 또는 마지막에 발생한 이벤트에 대해 한 번만 처리하는 것var debounce = function (eventName, func, wait) {
var timeoutId = null;
return function (event) {
var self = this;
console.log(eventName, 'event발생');
clearTimeout(timeoutId);
timeoutId = setTimeout(func.bind(self, event), wait);
}
}
var wheelHandler = function (e) {
console.log('wheel event 처리');
}
document.body.addEventListener('mousewheel', debounce('wheel', wheelHandler, 700));
여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인형태로 구성한 것
커링은 한번에 하나의 인자만 전달하는 것을 원칙으로 함
중간과정상의 함수를 실행한 결과는 그 다음 인자를 받기위해 대기만 할 뿐으로 마지막 인자가 전달되기 전까지는 원본함수가 실행되지 않음
지연실행
var getInformation = (baseUrl) => (path) => (id) => {
console.log(baseUrl + path + '/' + id);
return baseUrl + path + '/' + id;
};
var imageUrl = 'http://image.com/';
var productUrl = 'http://product.com/';
//이미지 타입별 요청 함수 준비
var getImage = getInformation(imageUrl);
var getEmoticon = getImage('emoticon');
var getIcon = getImage('icon');
//제품 타입별 요청 함수 준비
var getProduct = getInformation(productUrl);
var getFruit = getProduct('fruit');
var getVegetable = getProduct('vegetable');
//실제 요청
var emoticon1 = getEmoticon(100);
var emoticon2 = getEmoticon(102);
var icon1 = getIcon(205);
var icon2 = getIcon(227);
var fruit1 = getFruit(300);
var fruit2 = getFruit(400);
var vegetable1 = getVegetable(901);
var vegetable1 = getVegetable(942);