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)
所以我开始阅读返回其他函数或返回自己的函数.
我会继续尝试,但如果有人有一个光滑的解决方案,我很乐意看到它!
我写了一个函数,它生成一个链,其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)
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)