add(1)(2)(3).total === 6 - 有没有人见过像这样使用的自返回函数

add(1)(2)(3).total === 6 - Has anyone else seen self returning functions used like this?

本文关键字:像这样 函数 返回 total add 没有人      更新时间:2023-09-26

以下代码有效,虽然我理解它为什么有效,但我在任何地方都没有看到它。我认为这是因为所有其他设计模式都要好得多。

我仍然希望将这个例子视为一个警示故事,但我没有。

当然,这很糟糕,尤其是我选择下面的示例,因为它很清楚它的作用,但是:

这种模式叫什么?

常用吗?

是否有任何使用此模式的合法项目?

var add = function container (val) {
  addFunc = function f (val, undefined) {
  addFunc.total += val;
  return addFunc;
  };
addFunc.total = 0;
return addFunc(val);
};
alert(add(1)(2)(3).total);
alert(add(1)(2)(33).total);

编辑:更改变量名称,以便代码在IE中工作。

从技术上讲,这可以被认为是链接或封装。

当可以无限期地从原始函数执行一组操作时,可以链接。 jQuery 使用这种形式,当您可以将调用链接起来以设置原始选择器的属性和属性时。在这种情况下,创建者希望能够链接要添加的调用,而无需重新键入函数名称。不是最干净的想法,但有效。

此外,由于代码的实际主体永远不会向调用方公开,因此这也可以被视为封装,因为addFunc方法不会向外部范围公开。

这是一个称为currying的函数式编程概念。

本质上,给定一个function foo(a, b, c),您创建一个返回function bar2(b)返回给出最终答案function bar3(c)function bar(a)

从技术上讲,这不是真正的咖喱,因为它无限进行并使用副作用(total属性)来打破无限循环。

但无论如何,这种模式都可以有有用的应用。它对于遍历树结构特别有用,在树结构中,您正在计算树的每个叶子的一些结果,其中结果取决于该叶子的祖先。在根节点上运行 curried 函数,然后在每个子节点上运行返回的函数,然后为每个子节点运行返回的函数,依此类推。如果纯柯里函数运行的节点有子节点,它将返回另一个函数,如果到达叶子,则会返回所需的值。

代码将是一个简单的递归函数,它向自身传递一个新的"根"节点和用于解析它的函数,该函数始终接受一个参数。

但是,它在这里的使用方式看起来更像是一种学习练习,而不是有用的东西。

编辑:如果你想让它成为一个纯粹的柯里函数,但仍然有准无限递归,输入数据需要提供停止信息(就像C字符串使用值0x00来定义EOF):

var add = (function() {
    var total = 0;
    return function nextAdd(a) {
        if(a != null) {
            total += a;
            return nextAdd;
        } else {
            return total;
        }
    };
})();

然后,add(1)(2)(3)(null) === 6并且没有.total副作用参数。

你会无限

好:

function add() {
    var l = arguments.length, i, sum = 0;
    for( i=0; i<l; i++) sum += arguments[i];
    return sum;
}
alert(add(1,2,3)); // 6

真的,你问的代码风格应该没有理由。我没有看到任何合法的使用,只有任意arguments长度。

被称为Currying wikipedia。来自Haskell Curry维基百科的名称(但最初由Moses Ilyich Schönfinkel维基百科开发)。

一种转换函数的技术,该函数采用多个参数(或参数的 n 元组),可以将其称为函数链,每个函数具有单个参数(部分应用程序)。

来自 JavaScript 模式 2010:

何时使用 Currying - 当您发现自己调用相同的函数并传递几乎相同的参数时,则该函数可能是 currying 的良好候选者。您可以通过将一组参数部分应用于函数来动态创建新函数。新函数将存储重复的参数(因此您不必每次都传递它们),并使用它们来预填充原始函数所需的完整参数列表。

达斯汀·迪亚兹的另一篇文章。