当没有传递任何参数括号时,任何人都能解释这个函数如何发出警报。我无法清楚地理解它。
function sum(a) {
var sum = a
function f(b) {
sum += b
return f
}
f.toString = function() { return sum }
return f
}
alert( sum(1)(2) ) // 3
alert( sum(5)(-1)(2) ) // 6
alert( sum(6)(-1)(-2)(-3) ) // 0
alert( sum(0)(1)(2)(3)(4)(5) ) // 15
答案 0 :(得分:18)
第一次调用函数时,第一个值存储在sum
中。之后将返回function f(b)
,将临时结果保留在sum
。每次连续调用都会执行函数f
- 执行sum += b
并再次返回f。如果需要字符串上下文(例如在alert
或console.log
中),则调用f.toString
,返回结果(sum
)。
function sum(a) {
var sum = a
function f(b) {
sum += b
return f //<- from second call, f is returned each time
// so you can chain those calls indefinitely
// function sum basically got "overridden" by f
}
f.toString = function() { return sum }
return f //<- after first call, f is returned
}
说明:
alert( sum(6)(-1)(-2)(-3) ) // 0
/\ function sum called, f returned
/\ the returned function f is called, f returns itself
/\ again
/\ and again
/\ at last, alert() requires string context,
so f.toString is getting invoked now instead of f
答案 1 :(得分:3)
要看的是这段代码
function f(b) {
sum += b
return f
}
此函数返回对自身的引用,因此可以尽可能多地调用它。一个重要的事情是它有一个被调用的tostring函数,因为tostring是在函数sum()
中定义的,它可以访问变量sum
及其值当前值(由{{更改) 1}})
答案 2 :(得分:2)
alert
需要一个字符串。如果它没有得到一个字符串,它将尝试将它接收的任何对象(以及一个函数是一种对象)转换为一个。如果对象具有toString
方法,则将调用该方法以执行所述转换。
答案 3 :(得分:1)
sum
和f
函数始终返回f
函数,您可以无限次地调用它而不会获得除函数之外的其他结果。
该值仅由toString
的覆盖f
方法返回(实际上返回一个数字):
console.log( sum(1)(2) ) // Function(){}
console.log( sum(1)(2).toString() ) // 3
alert
函数在将其参数转换为字符串时隐式调用toString
方法。
答案 4 :(得分:0)
它在所有情况下都没有按预期工作......问题是.toString
应该返回一个字符串,因此提供的实现中的字符串方法不起作用,例如: G。 sum(2)(3).split()
会导致错误。
虽然我们可能会假设sum()
结果总是预期是一个数字,但在某些情况下可能不是这样,并且可能很难调试,例如: G。当我在jsbin.com上测试最初用.toString
编写的代码时,我注意到了这个问题(它在内部的console.log参数上执行split
,覆盖它。)
相反,.toString
应该看起来像return String(result);
。 .toString
(当没有.valueOf
或现代Symbol.toPrimitive
)处理原语转换时,好的事情就是如此,因此期望数字的代码也会起作用。这里可能出现的问题可能是&#34; double&#34;由此引起的转换。
如果您只针对现代浏览器,则更好的解决方案可能是使用.toString
和.valueOf
对,或只使用一个Symbol.toPrimitive
。
使用Symbol.toPrimitive
的示例:
function sum(a) {
let result = a;
function f(b) {
result += b;
return f;
}
f[Symbol.toPrimitive] = hint => hint === 'string' ? String(result) : result;
return f;
}
使用.toString
和.valueOf
对的示例。
function sum(a) {
var result = a;
function f(b) {
result += b;
return f;
}
// avoiding double conversion which will happen in case of .toString
f.valueOf = function() { return result; };
f.toString = function() { return String(result); };
return f;
}