인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.
함수형 프로그래밍은 프로그래밍의 여러 가지 패러다임 중 하나이다. 함수의 조합으로 작업을 수행하는 프로그래밍 방식이다. 중요한 것은 이 작업이 이루어 지는 동안 작업에 필요한 데이터와 상태는 변하지 않는다는 점이다. 변할 수 있는 건 오직 함수 뿐이다.
자바스크립트에서의 함수형 프로그래밍은 다음과 같은 자바스크립트의 특징 때문에 가능하다.
- 일급 객체로서의 함수
- 클로저
1.Memoization Pattern
//Memoization이란 계산 결과를 저장해 놓아 이후 다시 계산할 필요 없이 사용할 수 있게 한다는 컴퓨팅 용어이다.
//말 그대로 함수의 키값에 결과를 저장해두고 이후 계산없이 사용할 수 있다.
//왠지 아래 함수보다는 input, func 값으로 key값을 만들어서 하면 이후 똑같은 호출 시 계산없이해서 좋을 거 같다.
//jQuery에서는 data()라는 메서드로 이 메모이제이션 패턴을 사용하였다.
function Calculate(key, input, func){
Calculate.data = Calculate.data || {};
if(!Calculate.data[key]){
var result;
result = func(input);
Calculate.data[key] = result;
}
return Calculate.data[key];
}
var result;
result = Calculate(1,5,function(input){
return input * input;
});
console.log(result);
result = Calculate(2, 5, function(input){
return input * input /4;
});
console.log(result);
console.log(Calculate(1));
console.log(Calculate(2));
1) Memoization을 적용한 Factorial
//클로저를 활용한 앞서 실행한 factorial 값을 저장하는 factorial 함수
var factorial = function(){
var cache = {'0':1};
//연산을 수행하는 과정에서 캐시에 저장된 값이 있으면 곧바로 그 값을 반환한다.
var factorial = function(n){
var result = 0;
if(typeof(cache[n]) === 'number'){
result = cache[n];
} else {
result = cache[n] = n * factorial(n-1);
}
return result
};
return factorial;
}();
console.log(factorial(10));
console.log(factorial(12));
2) Memoization을 적용한 Fibonaci
//메모이제이션 기법을 적용한 피보나치 수열
var fibo = function(){
var cache = {'0' : 0, '1': 1};
var fibo = function(n){
if(typeof(cache[n]) === 'number'){
result = cache[n];
} else {
result = cache[n] = fibo(n-1) + fibo(n-2);
}
return result;
}
return fibo;
}();
console.log(fibo(10));
2.함수 적용
apply(), bind(), call() 함수는 함수형 프로그래밍에서 중요한 함수들이다.
3.Currying
커링이란 특정 함수에서 정의된 인자의 일부를 넣어 고정시키고, 나머지를 인자로 받는 새로운 함수를 만드는 것을 의미한다.
function calculate(a, b, c){
return a*b+c;
}
function curry(func){
var args = Array.prototype.slice.call(arguments, 1);
return function(){
return func.apply(null, args.concat(Array.prototype.slice.call(arguments)));
}
}
var new_func1 = curry(calculate, 1);
console.log(new_func1(2,3)); //5
var new_func2 = curry(calculate, 1, 2);
console.log(new_func2(3));//5
커링이란 특정 함수에서 정의된 인자의 일부를 넣어 고정시키고, 나머지를 인자로 받는 새로운 함수를 만드는 것을 의미한다.
bind() 함수가 커링과 매우 유사하다.
//bind() 함수는 고정시키고자 하는 인자를 함수 호출시 전달하고, 반환받은 함수를 호출하면서 나머지 가변 인자를 넣어줄 수 있다.
Function.prototype.bind = function(thisArg){
var fn = this;
slice = Array.prototype.slice;
args = slice.call(arguments, 1);
return function(){
return fn.apply(thisArg, args.concat(slice.call(arguments)));
};
}
4.wrapper
특정 함수를 자신의 함수로 덮어쓰는 것을 말한다. 물론 여기서 사용자는 원래 함수 기능을 잃어버리지 않은 상태로 자신의 로직을 수행할 수 있어야 한다.
기존 제공하는 함수에 기능을 추가하고 싶거나, 버그를 피하고자 할 때 많이 사용된다.
function wrap(object, method, wrapper){ var fn = object[method]; return object[method] = function(){ //original에서의 this와 익명함수 wrapper에서의 this가 다르므로 동일하게 만든다. return wrapper.apply(this, [fn.bind(this)].concat(Array.prototype.slice.call(arguments))); }; }
//original 함수가 있고, 이는 인자로 넘어온 값을 value에 할당하고 출력하는 기능을 한다. Function.prototype.original = function(value){ this.value = value; console.log("value : " + this.value); } //이를 사용자가 덮어쓰기 위해 wrap 함수를 호출하였다. 세 번째 인자로 넘긴 자신의 익명 함수를 original에 덮어쓰는 것이다. //여기서 사용자는 자신의 익명 함수의 첫 번째 인자로 원래 함수의 참조를 받을 수 있다. 이로 인해 원래 로직을 수행 할 수 있다. var mywrap = wrap(Function.prototype, "original", function(orig_func, value){ orig_func(value); console.log("wrapper value : " + this.value); }); var obj = new mywrap("song");
'Web Front > Javascript' 카테고리의 다른 글
| [InsideJavascript] 10. 자바스크립트에서의 객체지향 프로그래밍 (0) | 2018.05.20 |
|---|---|
| 위도, 경도 to Pt (0) | 2018.05.03 |
| [InsideJavascript] 9. 클로저 (0) | 2018.04.27 |
| [InsideJavascript] 8. 스코프 체인 (0) | 2018.04.27 |
| [InsideJavascript] 7. 실행 컨텍스트 (0) | 2018.04.27 |