要求寫一個函數add(),分別實現能以下效果:html
(1)console.log(add(1)(2)(3)(4)());//10 (2)console.log(add(1,2)(3,4)());//10 (3)console.log(add(1,2)(3,4));//10
針對(1)和(2),有兩種思路實現:純閉包思路和函數柯里化思路。數組
(1)的解決方案(閉包實現)閉包
function add(arg) { // body... let sum = 0; sum+=arg; return function (tmarg) { // body... if (arguments.length == 0) { return sum; }else{ sum+=tmarg; return arguments.callee; } } }
(2)的解決方案app
function add(arg) { // body... let sum = 0; sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum); return function (tmarg) { // body... if (arguments.length == 0) { return sum; }else{ sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum); return arguments.callee; } } }
通俗的理解,因爲函數柯里化具備這樣的特性:它可以"積累"函數的參數(無論是foo(1,2,3)仍是foo(1)(2)(3)這種鏈式形式)),而且延遲執行。能夠將多個參數積累到一個數組中,在最後一步執行求和。
柯里化通用形式:函數
function curry(fn) { // body... var args = Array.prototype.slice.call(arguments,1); return function () { // body... var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); console.log(finalArgs); return fn.apply(null,finalArgs); }; }
(2)的解決方案:spa
function add() { let sum = 0; var _args = Array.prototype.slice.call(arguments); var tmpf = function(){ if(arguments.length === 0) { sum = _args.reduce((a,b) => {return a + b;},sum); } _args.push.apply(_args,[].slice.call(arguments)); return tmpf; } }
針對問題(3):prototype
function add(arg) { // body... let sum = 0; sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum); var tmpf = function (tmarg) { // body... if (arguments.length == 0) { return sum; }else{ sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum); return tmpf; } }; tmpf.toString = tmpf.valueOf = function () { // body... return sum; } return tmpf; }
完!code
轉載請註明原文出處:http://www.cnblogs.com/qcblog/p/6858947.htmlhtm