函数柯西化(经典面试题)

// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = Array.prototype.slice.call(arguments);

    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        _args.push(...arguments);
        return _adder;
    };

    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}

add(1)(2)(3)                // 6
add(1, 2, 3)(4)             // 10
add(1)(2)(3)(4)(5)          // 15
add(2, 6)(1)                // 9

加强理解版本

```js // v1: 实现一个精简版的curry函数 function curry(fn, ...args) { return function () { return fn.apply(this, args.concat([].slice.call(arguments))); } } function add(a, b) { return a + b; }

var addCurry = curry(add, 1, 2); console.log(addCurry());// 3 //或者 var addCurry = curry(add, 1); console.log(addCurry(2)); // 3 //或者 var addCurry = curry(add); console.log(addCurry(1, 2)); // 3

// v2: 上面的代码优化 function sub_curry(fn) { let args = [].slice.call(arguments, 1); return function () { return fn.apply(this, args.concat([].slice.call(arguments))); } }

function curry(fn, length) { length = length || fn.length; let slice = Array.prototype.slice;

return function () {

}

}

// 容易理解的版本 function curryFn(fn, args) { let length = fn.length; // 获取fn这个函数的参数数量 args = args || []; // 参数

return function () {
    let _args = args.slice(0);

    for (let i = 0; i < arguments.length; i++) {
        _args.push(arguments[i]);
    }

    if (_args.length < length) {
        return curryFn.call(this, fn, _args);
    }
    else {
        return fn.apply(this, _args);
    }
}

}

let fn = curryFn(function(a, b, c) { console.log([a, b, c]); });

fn("a", "b", "c") // ["a", "b", "c"] fn("a", "b")("c") // ["a", "b", "c"] fn("a")("b")("c") // ["a", "b", "c"] fn("a")("b", "c") // ["a", "b", "c"] ```

results matching ""

    No results matching ""