Javascript函数挑战add(1,2)和add(1)(2)都应返回3

Mic*_*Fin 4 javascript closures function challenge-response

我的一个朋友要求我编写一个适用于这两种情况的函数

add(2,4)  // 6
add(2)(4) // 6
Run Code Online (Sandbox Code Playgroud)

我的本能是写一个返回自己的add()函数,但我不确定我是朝着正确的方向前进.这失败了.

function add(num1, num2){
    if (num1 && num2){
        return num1 + num2;
    } else {
        return this;
    }
}

alert(add(1)(2));
Run Code Online (Sandbox Code Playgroud)

所以我开始阅读返回其他函数或返回自己的函数.

我会继续尝试,但如果有人有一个光滑的解决方案,我很乐意看到它!

Pat*_*rts 8

我写了一个函数,它生成一个链,其valueOf函数和上下文(the this)不断用新的sum更新,无论每次传递多少个参数.

/* add function */
function add() {
    "use strict";

    var args, sum, chain;

    args = Array.prototype.slice.call(arguments);
    sum = typeof this === 'number' ? this : 0;
    sum += args.reduce(function (p, n) { return p + n; }, 0);

    chain = add.bind(sum);

    chain.valueOf = function () {
        return sum;
    };

    return chain;
}

/* tests */
console.log('add(1, 2) = ' + add(1, 2));
console.log('add(1)(2) = ' + add(1)(2));
/* even cooler stuff */
console.log('add(1, 2)(3) = ' + add(1, 2)(3));
console.log('add(1, 2, 3)(4, 5)(6) = ' + add(1, 2, 3)(4, 5)(6));
/* retains expected state */
var add7 = add(7);
console.log('var add7 = add(7)');
console.log('add7(3) = ' + add7(3));
console.log('add7(8) = ' + add7(8));
Run Code Online (Sandbox Code Playgroud)

之所以需要这两种机制,是因为链中的下一个调用无法访问绑定函数的自定义valueOf,并且任何尝试将函数作为数字进行求值的脚本都无法访问其上下文.

唯一的缺点是要求strict mode,以便this保持原始.

这是一个支持两种strict mode和非严格模式的编辑:

function add() {
    var args, sum, chain;

    args = Array.prototype.slice.call(arguments);

    // Number object from non-strict mode
    if (this instanceof Number) {
        sum = Number(this);
    // number primitive from strict mode
    } else if (typeof this === 'number') {
        sum = this;
    // initial call to add
    } else {
        sum = 0;
    }

    sum += args.reduce(function (p, n) { return p + n; }, 0);

    chain = add.bind(sum);

    chain.valueOf = function () {
        return sum;
    };

    return chain;
}
Run Code Online (Sandbox Code Playgroud)


and*_*dih 6

Dr.Dobs Journal上有一篇关于" JavaScript中的Currying和Partial Functions "的文章,它描述了这个问题.

本文中的一个解决方案是:

// a curried add
// accepts partial list of arguments
function add(x, y) {
     if (typeof y === "undefined") { // partial
        return function (y) {
              return x + y;
        };
     }
   // full application
   return x + y;
}
Run Code Online (Sandbox Code Playgroud)

  • 而不是`typeof y ==="undefined"`try` arguments.length <2`,以防`undefined`显式传递给`y`. (4认同)