【问题标题】:How to understand “add(1)(2)(3)=6”?如何理解“add(1)(2)(3)=6”?
【发布时间】:2020-06-01 03:59:46
【问题描述】:

我正在学习 javascript 中的 curry 函数。 我想到了一个问题。

// how to implement the add function in the below.

add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

我已经知道实现的代码

function add() {
var _args = Array.prototype.slice.call(arguments);
var _adder = function () {
    _args.push(...arguments);
    return _adder;
};
_adder.toString = function () {
    return _args.reduce(function (a, b) {
        return a + b;
    });
}
return _adder;
}
console.log(add(1)(2)(3)(4)(5))    // function 
console.log(add(1)(2)(3))          // function
console.log(add(1, 2, 3)(4))       // function

console.log(add(1)(2)(3)(4)(5) == 15)  // true 
console.log(add(1)(2)(3) == 6)         // true
console.log(add(1, 2, 3)(4) == 10)     // true

console.log(add(1)(2)(3)(4)(5) === 15)  // false
console.log(add(1)(2)(3) === 6)         // false
console.log(add(1, 2, 3)(4) === 10)     // false

我知道实现的代码是如何工作的。 但我对这个问题很好奇。 在我看来,“add(1)(2)(3) = 6;”意味着执行表达式“add(1)(2)(3)”后,它应该返回一个完全等于数字 6 的值.但是从这个问题及其实现代码来看,我可能对这个问题有误解。那么,这个问题的真正含义是什么?面试官经常会问这个问题。

【问题讨论】:

  • 在我的 Chrome 浏览器上,前三个案例返回数字 15、6 和 10,而不是“函数”。
  • 另外两个变体:console.log(typeof add(1)(2)(3)(4)(5)) 返回“function”,console.log(add(1)(2)(3)(4)(5) +0 === 15) 返回“true”。
  • 哦。这确实很奇怪。我也用铬。它的版本是 83。
  • 我只是在我的 safari(13.1 版)和 firefox(76 版)浏览器中测试代码。在 Firefox 中,前三种情况返回函数。在 safari 中,它返回数字 15、6 和 10。但是当我想查看“add(1)(2)(3)(4)(5)”的类型时,safari 只给我“函数”。

标签: javascript function tostring currying


【解决方案1】:

这归结为 JavaScript 运算符。

= 进行分配。

=== 进行正常的相等比较。函数永远不会等于数字。

== 对两个值进行麻烦的类型转换,然后进行相等测试。通常最好避免它。在这种情况下,这些类型转换可以将您的 curried 函数转换为字符串,如果其复杂的规则使其将第一个 arg 强制转换为运行您的 curried 函数的字符串,它可能会调用您的 toString 方法,并转换另一个参数为一个字符串,两个字符串相等。

这种自动转换和希望最好的测试很容易做错事。例子:

  • console.log(add(10)(-10) == '') --> 是的
  • console.log(add(10)(20) == 30) --> 是的
  • console.log(add(10)(20) == ' 30 ') --> 是的
  • console.log(add(10)(20) == 036) --> 是的
  • console.log(add(10)(20) == ' 036 ') --> 错误
  • console.log(add(10)(20) == ' 36 ') --> 错误
  • console.log(add(2)(-2) == []) -> 错误
  • console.log(0 == []) --> 是的

另见https://stackoverflow.com/a/359509/1682419

【讨论】:

  • @quan 这里的重点是.toString()是比较麻烦的方法。 console.log 正在调用 .toString(),它正在转换整数。这是一个关于柯里化的甜蜜资源javascript.info/currying-partials#advanced-curry-implementation
  • @djthoms 如果代码是console.log(add(1)(2)(3)(4)(5)),那么实际上console.log 将调用.toString()。但在这种情况下,代码相当于 console.log(… == 15),因此 JavaScript 在将 结果转换为字符串之前运行 == 运算符。
  • 我知道实现代码。并且当一个Object被强制转换为String的原始类型时,会依次调用toString和valueOf方法。毕竟谢谢你。我只是无法弄清楚问题的实际含义。
  • @quanlili 如果面试官的问题是“如何理解这个?”,我认为它的意思是“如何预测结果?”,“如果你对它进行小改动会发生什么”,以及“你什么时候或为什么会在编写软件时使用或避免使用它?”我不会在 JavaScript 中使用自柯里化函数,因为它的返回值以难以预测的方式与其他操作交互。在设计软件时,我们需要易于预测、易于修改、跨浏览器可靠的代码。
  • 在实际项目中编写这样的代码是个坏主意。但面试就是面试。
猜你喜欢
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 2011-09-08
相关资源
最近更新 更多