Javascript中带有多个括号的闭包
有谁能解释一下,当没有更多的参数被传递时,这个函数是如何发出警报的。我不能清楚地理解它Javascript中带有多个括号的闭包,javascript,closures,Javascript,Closures,有谁能解释一下,当没有更多的参数被传递时,这个函数是如何发出警报的。我不能清楚地理解它 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)
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
警报
需要一个字符串。如果它没有得到字符串,它将尝试将它接收到的任何对象(函数是对象的一种类型)转换为字符串。如果对象具有toString
方法,则将调用该方法来执行所述转换 要看的是这段代码
function f(b) {
sum += b
return f
}
此函数返回对自身的引用,以便尽可能多次调用它。重要的是它有一个tostring函数可以被调用,因为tostring是在函数
sum()
中定义的,所以它可以访问变量sum
及其当前值(该值由f()
更改)函数的sum
和f
总是返回f
函数,您可以无限次地调用它,而不会得到函数以外的结果
该值仅由f
的重写toString
方法返回(该方法实际返回一个数字):
alert
函数在将参数转换为字符串时隐式调用toString
方法。第一次调用函数时,第一个值存储在sum
中。之后,将返回函数f(b),并将临时结果保存在sum
中。在每次连续调用中,执行函数f
——执行sum+=b
,然后再次返回f。如果需要字符串上下文(例如在警报
,或控制台.log
),则调用f.toString
,返回结果(sum
)
在所有情况下,它都无法正常工作。。。问题是
.toString
应该返回一个字符串,因此提供的实现中的字符串方法将不起作用,例如。g<代码>总和(2)(3)。拆分()将导致错误
虽然我们可能会假设sum()
结果总是预期为一个数字,但在某些情况下可能不是真的,并且可能很难调试,例如。G当我最初仅在jsbin.com上测试使用.toString
编写的代码时,我注意到了这个问题(它在console.log参数上内部执行split
,覆盖它)
相反,.toString
应该看起来像返回字符串(结果)代码>。好消息是.toString
(当没有.valueOf
或现代符号.toPrimitive
时)将处理原语转换,因此需要数字的代码也可以工作。这里可能存在的问题可能是由此导致的“双重”转换
更好的解决方案可能是使用一对.toString
和.valueOf
或者只使用一个符号.toPrimitive
,如果您只针对现代浏览器
使用符号的示例。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;
}
所有对象都有一个toString
函数,只是在大多数情况下它是默认的“[object Constructorname]”格式。在这种情况下,该方法被重写以产生结果。基本上,在第一个警报和(1)(2)中是a&b,在第二个警报中是和(6)(-1)(2)。现在函数如何理解(2)也是f(b)参数。@Babu摆脱a和b的思想。您可以考虑调用一次sum()
,初始化var sum
,然后在第一次调用后被覆盖,通过调用f(b)
来处理每个连续调用(因为f本身每次都返回自身,从而可以进行进一步的链接),除非出现字符串上下文。现在清楚了吗?很好的解释。你能告诉我直接返回金额的代码吗。函数sum(a){var sum=a函数f(b){sum+=b return sum}//f.toString=function(){return sum}return f}sum(1)(2)@BabuArumugam:关键是你不能……你为什么需要这个?
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
function sum(a) {
let result = a;
function f(b) {
result += b;
return f;
}
f[Symbol.toPrimitive] = hint => hint === 'string' ? String(result) : result;
return f;
}
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;
}