인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.
함수형 프로그래밍은 프로그래밍의 여러 가지 패러다임 중 하나이다. 함수의 조합으로 작업을 수행하는 프로그래밍 방식이다. 중요한 것은 이 작업이 이루어 지는 동안 작업에 필요한 데이터와 상태는 변하지 않는다는 점이다. 변할 수 있는 건 오직 함수 뿐이다.
자바스크립트에서의 함수형 프로그래밍은 다음과 같은 자바스크립트의 특징 때문에 가능하다.
- 일급 객체로서의 함수
- 클로저
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 |