我试图通过闭包制作下一个:
function func(number) {
var result = number;
var res = function(num) {
return result + num;
};
return res;
}
var result = func(2)(3)(4)(5)(3);
console.log(result); // 17
我需要收到2 + 3 + 4 + 5 + 3 = 17 但我得到一个错误:未捕获TypeError:数字不是函数
答案 0 :(得分:8)
你误用了你的功能。
func(2)
会返回res
函数
使用(3)
调用该函数会返回数字5
(通过return result + num
)。
5
不是函数,因此(4)
会出错。
答案 1 :(得分:8)
您必须以某种方式表示链的末尾,您将返回结果编号而不是其他函数。您可以选择:
func(n)
),以提供sum
curried个参数的数量。null
)。在函数对象上创建一个返回值的方法。 valueOf()
非常适合,因为当函数转换为原始值时将调用它。看到它在行动:
function func(x) {
function ret(y) {
return func(x+y);
}
ret.valueOf = function() {
return x;
};
return ret;
}
func(2) // Function
func(2).valueOf() // 2
func(2)(3) // Function
func(2)(3).valueOf() // 5
func(2)(3)(4)(5)(3) // Function
func(2)(3)(4)(5)(3)+0 // 17
答案 2 :(得分:3)
嗯,(2)(3)部分是正确的。调用func(2)将返回res
,这是一个函数。但是,调用(3)将返回res
的结果,这是一个数字。所以当你试着打电话给(4)时会出现问题。
对于你想要做的事情,我没有看到Javascript如何预测你是在链的末尾,并决定返回一个数字而不是一个函数。也许你可以使用对象属性以某种方式返回具有“结果”属性的函数,但大多数情况下我只是好奇你为什么要这样做。显然,对于你的具体例子,最简单的方法就是将数字加在一起,但我猜你会更进一步。
答案 3 :(得分:0)
如果你想继续调用它,你需要继续返回一个函数,直到你想要你的答案。例如5次调用
function func(number) {
var result = number,
iteration = 0,
fn = function (num) {
result += num;
if (++iteration < 4) return fn;
return result;
};
return fn;
}
func(2)(3)(4)(5)(3); // 17
你也可以做更多长度的事情,就像这样
function func(number) {
var result = number,
fn = function () {
var i;
for (i = 0; i < arguments.length; ++i)
result += arguments[i];
if (i !== 0) return fn;
return result;
};
return fn;
}
func(2)(3, 4, 5)(3)(); // 17
答案 4 :(得分:0)
我将此标记为重复,但由于此问题中也缺少此选项,我将在此处添加。如果我理解正确为什么你会认为这很有趣(有一个任意函数顺序应用于值列表,累积结果),你还应该研究reduce
:
function sum(a, b) {
return a + b;
}
a = [2, 3, 4, 5, 3];
b = a.reduce(sum);
答案 5 :(得分:0)
另一个解决办法可能就是调用没有参数的函数来获得结果,但如果用params调用它就会增加总和。
function add() {
var sum = 0;
var closure = function() {
sum = Array.prototype.slice.call(arguments).reduce(function(total, num) {
return total + num;
}, sum);
return arguments.length ? closure : sum;
};
return closure.apply(null, arguments);
}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)); // function(){}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)()); // 30;
答案 6 :(得分:0)
我们可以使用几个辅助函数identity
和sumk
轻松完成它。
sumk
使用延续来保留挂起的 add 计算的堆栈,并在调用第一个0
时用()
展开堆栈。
const identity = x => x
const sumk = (x,k) =>
x === undefined ? k(0) : y => sumk(y, next => k(x + next))
const sum = x => sumk(x, identity)
console.log(sum()) // 0
console.log(sum(1)()) // 1
console.log(sum(1)(2)()) // 3
console.log(sum(1)(2)(3)()) // 6
console.log(sum(1)(2)(3)(4)()) // 10
console.log(sum(1)(2)(3)(4)(5)()) // 15