【问题标题】:How can I make var a = add(2)(3); //5 work?我怎样才能使 var a = add(2)(3); //5 工作?
【发布时间】:2010-02-16 12:44:10
【问题描述】:

我想让这种语法成为可能:

var a = add(2)(3); //5

基于我在http://dmitry.baranovskiy.com/post/31797647阅读的内容

我不知道如何使它成为可能。

【问题讨论】:

标签: javascript currying


【解决方案1】:

您需要 add 成为一个函数,该函数接受一个参数并返回一个函数,该函数接受一个将参数添加到 add 和自身的参数。

var add = function(x) {
    return function(y) { return x + y; };
}

【讨论】:

  • ES2015 箭头语法有助于这项工作:const add = x => y => x + y;
  • @tvanfosson 我是 JS 新手。我有一个疑问。为什么它(var add = function() 不应该是function add(){ }function add() 也给出相同的结果。
  • @mkHun 我展示的语法定义了一个匿名函数并将其分配给名为add 的变量。第二个定义了一个名为add 的命名函数。它们都有效。
  • @tvanfosson 我认为我下面的解决方案更令人兴奋,无限添加链
  • 你能告诉我,这种语法有什么具体的名字吗,昨晚我的面试官问了同样的问题
【解决方案2】:
function add(x) {
    return function(y) {
        return x + y;
    };
}

啊,JavaScript 的美妙之处

这个语法也很简洁

function add(x) {
    return function(y) {
        if (typeof y !== 'undefined') {
            x = x + y;
            return arguments.callee;
        } else {
            return x;
        }
    };
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6

【讨论】:

  • if (y) 应该是 if (typeof y === "undefined"),因为零是有效参数。
  • @dionadar 好吧,不完全是 (0) 将返回 x 的值,这不是一个函数,因此在使用 (0) 后您无法添加任何其他内容。
  • 我们可以做些什么来消除最后一个空括号,比如让 add(1)(2)(3) = 6 和 add(1)(2)(3)(4) = 10?我被要求写一个这样的函数,然后就被困住了。
  • 查看我的答案以获得没有最终 () 的解决方案
  • 你如何使它与一个参数以及柯里化一起工作,例如加法(1)=== 1,加法(1)(2)=== 3
【解决方案3】:
function add(x){
  return function(y){
    return x+y
  }
}

First-class functionsclosures 完成这项工作。

【讨论】:

    【解决方案4】:

    这是关于 JS curring 并且对valueOf 有点严格:

    function add(n){
      var addNext = function(x) {
        return add(n + x);
      };
    
      addNext.valueOf = function() {
        return n;
      };
    
      return addNext;
    }
    
    console.log(add(1)(2)(3)==6);//true
    console.log(add(1)(2)(3)(4)==10);//true
    

    它就像一个无限添加链的魅力!

    【讨论】:

    • const add = (a) => { let f = (b) => add(a + b) f.valueOf = () => a return f }
    • 赋值时到底发生了什么?!在这种情况下,您的相同示例的行为会有所不同: a) console.log(' 应该等于 6 => ', add(1)(2)(3)); b) console.log('应该不重要', add(1)(2)(3) === 6);你能解释一下幕后发生的事情吗(除了 rotenJS 这是显而易见的;))
    • 因为 func valueOf of add 会返回一个字符串
    • 它只用于数字比较。在最后一次add 调用之后如何获取值而不是函数体,有人吗?
    • 我知道在 cmets 中写“谢谢”是一个很大的禁忌。但就这一次,谢谢。真的。
    【解决方案5】:

    试试这个会在两个方面帮助你 add(2)(3) 和 add(2,3)

    1.)

     function add(a){ return function (b){return a+b;} }
    
        add(2)(3) // 5
    

    2.)

    function add(a,b){
            var ddd = function (b){return a+b;};
            if(typeof b =='undefined'){
                return ddd;
            }else{
                return ddd(b);
            }
        }
    
    add(2)(3) // 5
    add(2,3) // 5
    

    【讨论】:

      【解决方案6】:
      function add(n) {
        sum = n;
        const proxy = new Proxy(function a () {}, {
          get (obj, key) {
            return () => sum;
          },
          apply (receiver, ...args) {
            sum += args[1][0];
            return proxy;
          },
        });
        return proxy
      }
      

      适用于一切,不需要像其他解决方案那样在函数末尾使用 final ()。

      console.log(add(1)(2)(3)(10));    // 16
      console.log(add(10)(10));         // 20
      

      【讨论】:

      • 哇,你能解释一下吗,我不知道发生了什么。
      • 所以我在学习代理时主要参考了2ality.com/2014/12/es6-proxies.html,但简短的版本是在javascript中你可以为几乎所有操作创建陷阱。幸运的是,应用函数的操作与确定值的操作不同。所以我捕获了一个函数的 apply 和 getter 来创建它。你可能已经在你的 es6 类中使用 getter 和 setter (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) 这样做了,这只是更明确一点
      • @GaleelBhasha 不知道为什么 jsFiddle 不工作,但它在 repl.it (repl.it/repls/DirectPolitePasswords) 和我的本地节点 repl 中工作。
      • 代理还可以,但我认为我下面的答案更容易阅读!
      • @hien 我什至没有考虑过,这是一个非常酷的解决方案。
      【解决方案7】:

      ES6 语法让这一切变得简单易用:

      const add = (a, b) => a + b;
      
      console.log(add(2, 5)); 
      // output: 7
      
      const add2 = a => b => a + b;
      
      console.log(add2(2)(5));
      // output: 7
      

      【讨论】:

      • 你如何使它与一个参数以及柯里化一起工作,例如加法(1)=== 1,加法(1)(2)=== 3
      • @AymonFournier 我不是 100% 确定,但我认为 add(1) 不可能同时返回 Function 和 Number 值。在调用 add(1) 时,您无法确定是否会有另一个以2 为参数的调用,或者这是否是最终调用。
      • @AymonFournier 哦,我的立场是正确的,一个技巧是使用valueOf()。有关详细信息,请参阅其他人的答案:stackoverflow.com/a/51317189/964545
      【解决方案8】:

      箭头函数无疑使获得所需结果变得非常简单:

      const Sum = a => b => b ? Sum( a + b ) : a;
      
      console.log(Sum(3)(4)(2)(5)()); //14
      
      console.log(Sum(3)(4)(1)()); //8
      

      【讨论】:

      • 当你走到这一步时,它太棒了。而且很容易忘记 3+4+2+5 不是 19 :)
      【解决方案9】:

      这是一个通用解决方案,它将解决 add(2,3)()、add(2)(3)() 或任何组合,如 add(2,1,3)(1)(1)(2, 3)(4)(4,1,1)()。请注意,很少有安全检查未完成,可以进一步优化。

      function add() {
      	var total = 0;
      
      	function sum(){
      		if( arguments.length ){
      			var arr = Array.prototype.slice.call(arguments).sort();
      			total = total + arrayAdder(arr);
      			return sum;
      		}
      		else{
      			return total;
      		}
      	}
      
      	if(arguments.length) {
      		var arr1 = Array.prototype.slice.call(arguments).sort();
      		var mytotal = arrayAdder(arr1);
      		return sum(mytotal);
      	}else{
      		return sum();
      	}
      
      	function arrayAdder(arr){
      		var x = 0;
      		for (var i = 0; i < arr.length; i++) {
      			x = x + arr[i];
      		};
      		return x;
      	}
      }
      add(2,3)(1)(1)(1,2,3)();

      【讨论】:

        【解决方案10】:

        这两个都可以处理

        add(2,3) // 5
        

        add(2)(3) // 5
        

        这是一个 ES6 咖喱示例...

        const add = (a, b) => (b || b === 0) ? a + b : (b) => a + b;
        

        【讨论】:

          【解决方案11】:

          除了已经说过的,这里有一个通用柯里化的解决方案(基于http://github.com/sstephenson/prototype/blob/master/src/lang/function.js#L180

          Function.prototype.curry = function() {
              if (!arguments.length) return this;
              var __method = this, args = [].slice.call(arguments, 0);
              return function() {
                return __method.apply(this, [].concat(
                  [].slice.call(args, 0),
                  [].slice.call(arguments, 0)));
             }
          }
          
          
          add = function(x) {
              return (function (x, y) { return x + y }).curry(x)
          }
          
          console.log(add(2)(3))
          

          【讨论】:

          • 不错的解决方案,但有些人会反对在原型中添加东西
          【解决方案12】:

          这是 JS 中柯里化的概念。
          您的问题的解决方案是:

          function add(a) {
            return function(b) {
              return a + b;
            };
          }
          

          这也可以使用箭头函数来实现:

          let add = a => b => a + b;
          

          解决方案添加(1)(2)(5)(4)........(n)();使用递归

          function add(a) {
            return function(b){
              return b ? add(a + b) : a;
            }
          }
          

          使用 ES6 箭头函数 语法:

          let add = a => b => b ? add(a + b) : a;
          

          【讨论】:

            【解决方案13】:

            在这种情况下可以使用闭包的概念。
            函数“add”返回另一个函数。返回的函数可以访问父作用域中的变量(在本例中为变量 a)。

            function add(a){
            
                return function(b){
                    console.log(a + b);
                }
            
            }
            
            
            add(2)(3);
            

            这里是了解闭包的链接http://www.w3schools.com/js/js_function_closures.asp

            【讨论】:

              【解决方案14】:
              const add = a => b => b ? add(a+b) : a;
              
              console.log(add(1)(2)(3)());
              

              (`${a} ${b}`) 用于字符串。

              【讨论】:

                【解决方案15】:

                使用 ES6 扩展 ... 运算符和 .reduce 函数。使用该变体,您将获得链接语法,但此处需要最后一次调用 (),因为始终返回函数:

                function add(...args) {
                    if (!args.length) return 0;
                    const result = args.reduce((accumulator, value) => accumulator + value, 0);
                    const sum = (...innerArgs) => {
                        if (innerArgs.length === 0) return result;
                        return add(...args, ...innerArgs);    
                    };
                    return sum;
                }
                
                
                
                
                // it's just for fiddle output
                document.getElementById('output').innerHTML = `
                <br><br>add() === 0: ${add() === 0 ? 'true' : 'false, res=' + add()}
                <br><br>add(1)(2)() === 3: ${add(1)(2)() === 3 ? 'true' : 'false, res=' + add(1)(2)()}
                <br><br>add(1,2)() === 3: ${add(1,2)() === 3 ? 'true' : 'false, res=' + add(1,2)()}
                <br><br>add(1)(1,1)() === 3: ${add(1)(1,1)() === 3 ? 'true' : 'false, res=' + add(1)(1,1)()}
                <br><br>add(2,3)(1)(1)(1,2,3)() === 13: ${add(2,3)(1)(1)(1,2,3)() === 13 ? 'true' : 'false, res=' + add(2,3)(1)(1)(1,2,3)()}
                `;
                &lt;div id='output'&gt;&lt;/div&gt;

                【讨论】:

                  【解决方案16】:
                  function add(a, b){
                   return a && b ? a+b : function(c){return a+c;}
                  }
                  
                  console.log(add(2, 3));
                  console.log(add(2)(3));
                  

                  【讨论】:

                    【解决方案17】:

                    这个问题已经激发了很多答案,我的“两便士价值”肯定不会破坏事情。

                    我对尝试添加“我最喜欢的”功能的众多方法和变化感到惊讶,即。 e. 我想在这样的柯里化函数中找到的那些,使用一些 ES6 符号:

                    const add=(...n)=>{
                     const vsum=(a,c)=>a+c;
                     n=n.reduce(vsum,0);
                     const fn=(...x)=>add(n+x.reduce(vsum,0));
                     fn.toString=()=>n; 
                     return fn;
                    }
                    
                    let w=add(2,1); // = 3
                    console.log(w()) // 3
                    console.log(w); // 3
                    console.log(w(6)(2,3)(4)); // 18
                    console.log(w(5,3)); // 11
                    console.log(add(2)-1); // 1
                    console.log(add()); // 0
                    console.log(add(5,7,9)(w)); // 24
                    .as-console-wrapper {max-height:100% !important; top:0%}

                    基本上,这个递归编程函数中没有什么是新的。但它确实适用于上述任何答案中提到的所有可能的参数组合,并且最后不需要“空参数列表”。

                    您可以在任意数量的柯里化级别中使用任意数量的参数,结果将是另一个可重复用于相同目的的函数。我使用了一个小“技巧”​​来“同时”获得一个数值:我重新定义了内部函数fn.toString() 函数!每当使用没有参数列表和“预期某些值”的函数时,Javascript 都会调用此方法。从技术上讲,它是一种“hack”,因为它不会返回一个字符串而是一个数字,但它会以一种在大多数情况下是“期望”的方式工作。试一试!

                    【讨论】:

                      【解决方案18】:

                      也可以试试这个:

                      let sum = a => b => b ? sum(a + b) :a
                      console.log(sum(10)(20)(1)(32)())   //63
                      

                      【讨论】:

                        【解决方案19】:
                        const sum  = function (...a) {
                            const getSum = d => {
                                return d.reduce((i,j)=> i+j, 0);
                            };
                        
                            a = getSum(a);
                            return function (...b) {
                                if (b.length) {
                                    return sum(a + getSum(b)); 
                                }
                                return a;
                            }
                        };
                        console.log(sum(1)(2)(3)(4,5)(6)(8)())
                        

                        【讨论】:

                          【解决方案20】:

                          函数添加(){ var sum = 0;

                              function add() {
                                  for (var i=0; i<arguments.length; i++) {
                                      sum += Number(arguments[i]);
                                  }
                                  return add;
                              }
                              add.valueOf = function valueOf(){
                                  return parseInt(sum);
                              };
                              return add.apply(null,arguments);
                          }
                          
                          // ...
                          
                          console.log(add() + 0);               // 0
                          console.log(add(1) + 0);/*                 // 1
                          console.log(add(1,2) + 0);               // 3
                          

                          【讨论】:

                            【解决方案21】:
                            function A(a){
                              return function B(b){
                                  return a+b;
                              }
                            }
                            

                            我为这种方法找到了一个很好的解释。它被称为闭包语法

                            请参考此链接 Syntax of Closures

                            【讨论】:

                              【解决方案22】:

                              我们可以这样写一个函数

                                  function sum(x){
                                    return function(y){
                                      return function(z){
                                        return x+y+z;
                                      }
                                    }
                                  }
                              
                                  sum(2)(3)(4)//Output->9
                              

                              【讨论】:

                                【解决方案23】:

                                不要复杂。

                                var add = (a)=>(b)=> b ? add(a+b) : a;
                                console.log(add(2)(3)()); // Output:5
                                

                                它将在最新的 javascript (ES6) 中工作,这是一个递归函数。

                                【讨论】:

                                  【解决方案24】:

                                  这里我们使用闭包的概念,其中所有在 main 函数中调用的函数 iter 引用和更新 x,因为它们有闭包。无论循环多长时间,直到最后一个函数,都可以访问 x

                                  function iter(x){    
                                  return function innfunc(y){
                                  //if y is not undefined
                                  if(y){
                                  //closure over ancestor's x
                                  x = y+x;
                                  return innfunc;
                                  }
                                  else{
                                  //closure over ancestor's x
                                  return x;
                                      }
                                    }
                                  }
                                  

                                  iter(2)(3)(4)() //9 iter(1)(3)(4)(5)() //13

                                  【讨论】:

                                    【解决方案25】:

                                    let multi = (a)=>{
                                    	return (b)=>{
                                    		return (c)=>{
                                    			return a*b*c
                                    		}
                                    	}
                                    }
                                    multi (2)(3)(4) //24

                                    let multi = (a)=> (b)=> (c)=> a*b*c;
                                    multi (2)(3)(4) //24

                                    【讨论】:

                                      【解决方案26】:

                                      我们可以使用闭包来完成这项工作。

                                          function add(param1){
                                            return function add1(param2){
                                            return param2 = param1 + param2;
                                          }
                                        }
                                        console.log(add(2)(3));//5
                                      

                                      【讨论】:

                                        【解决方案27】:

                                        我想出了一个很好的闭包解决方案,内部函数可以访问父函数的参数访问并存储在其词法范围内,每当我们执行它时,都会得到答案

                                            const Sum = function (a) {
                                                return function (b) {
                                                    return b ? Sum(a + b) : a;
                                                }
                                            };
                                        
                                            Sum(1)(2)(3)(4)(5)(6)(7)() // result is 28
                                            Sum(3)(4)(5)() // result is 12
                                            Sum(12)(10)(20) // result is 42
                                        

                                        enter image description here

                                        【讨论】:

                                        • 您好,欢迎来到 stackoverflow,感谢您的回答。您能否简单地解释一下您解决了什么问题以及您是如何解决的,而不是仅仅发布一段代码?这将有助于以后发现此问题的人更好地了解该问题以及如何处理它。
                                        【解决方案28】:

                                        您应该进入 currying 以调用上述格式的函数。

                                        理想情况下,将两个数字相加的函数如下所示:

                                        let sum = function(a, b) {
                                          return a + b;
                                        }

                                        同样的函数可以转化为,

                                        let sum = function(a) {
                                          return function(b) {
                                            return a+b;  
                                          }
                                        }
                                        
                                        console.log(sum(2)(3));

                                        让我们了解它是如何工作的。

                                        当你调用 sum(2) 时,它会返回

                                        function(b) {
                                            return 2 + b;
                                        }
                                        

                                        当用 3 进一步调用返回的函数时,b 取值 3。返回结果 5。

                                        更详细的解释:

                                        let sum = function(a) {
                                          return function(b) {
                                            return a + b;
                                          }
                                        }
                                        
                                        let func1 = sum(2);
                                        console.log(func1);
                                        
                                        let func2 = func1(3)
                                        console.log(func2);
                                        
                                        //the same result can be obtained in a single line
                                        
                                        let func3 = sum(2)(3);
                                        console.log(func3);
                                        
                                        //try comparing the three functions and you will get more clarity.

                                        【讨论】:

                                          【解决方案29】:

                                          以下用例的简单递归解决方案

                                          添加(); // 0

                                          添加(1)(2)(); //3

                                          添加(1)(2)(3)(); //6

                                          function add(v1, sum = 0) {
                                               if (!v1) return sum;
                                                sum += v1
                                               return (v2) => add(v2, sum);
                                          }
                                          

                                          【讨论】:

                                            【解决方案30】:

                                            function add () {
                                                var args = Array.prototype.slice.call(arguments);
                                             
                                                var fn = function () {
                                                    var arg_fn = Array.prototype.slice.call(arguments);
                                                    return add.apply(null, args.concat(arg_fn));
                                                }
                                             
                                                fn.valueOf = function () {
                                                    return args.reduce(function(a, b) {
                                                        return a + b;
                                                    })
                                                }
                                             
                                                return fn;
                                            }
                                            
                                            console.log(add(1));
                                            console.log(add(1)(2));
                                            console.log(add(1)(2)(5));

                                            来自http://www.cnblogs.com/coco1s/p/6509141.html

                                            【讨论】:

                                              猜你喜欢
                                              • 2012-08-21
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 2021-01-22
                                              • 2011-04-26
                                              • 1970-01-01
                                              • 2018-01-21
                                              相关资源
                                              最近更新 更多