add(1)(2)(3).total === 6 - 有没有人见过像这样使用的自返回函数
add(1)(2)(3).total === 6 - Has anyone else seen self returning functions used like this?
以下代码有效,虽然我理解它为什么有效,但我在任何地方都没有看到它。我认为这是因为所有其他设计模式都要好得多。
我仍然希望将这个例子视为一个警示故事,但我没有。
当然,这很糟糕,尤其是我选择下面的示例,因为它很清楚它的作用,但是:
这种模式叫什么?
常用吗?
是否有任何使用此模式的合法项目?
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 的良好候选者。您可以通过将一组参数部分应用于函数来动态创建新函数。新函数将存储重复的参数(因此您不必每次都传递它们),并使用它们来预填充原始函数所需的完整参数列表。
达斯汀·迪亚兹的另一篇文章。
- 如何将一个模态放在一边-显示其他模态(像..这样的向导)
- 箭头函数是否像命名函数一样进行了优化
- 无法使用“;测试”;作为javascript中的值,但可以使用像1这样的数字
- 用Javascript正则表达式检查像x.0.0这样的字符串
- 在保存到本地存储之前,如何修改我得到的 json 响应以使其看起来像这样
- 如何使用javascript和php检查符号,像这样
- 是否可以像这样在卸载之前写入
- 为什么 js 在像 '{}[0]' 这样的语句中忽略 '{}'
- 正确的选择器字符串是什么,可以在像这样结构的 HTML 中获取我想要的特定元素
- 如何像这样显示时间,例如:1秒前,1分钟前,1小时前,1个月前
- 如何使用getElementsByClassName检查输入中的值,像这样
- 使用原型表现得像“二传手函数”
- 如何在示例中构建像这样的简单图像旋转效果
- 使用哪个插件来调整图像大小,就像这样
- 为什么像这样向 JavaScript 引用类型添加方法不起作用
- add(1)(2)(3).total === 6 - 有没有人见过像这样使用的自返回函数
- 仅数字的 ng 模式将接受像 “-” 这样的字符,例如 Angular.js
- 如何使与jquery延迟对象一起工作的函数表现得像同步函数
- 如何更改'还有一个像这样的人'当I'我已经把它添加到我的网站上了
- 使用像$这样的函数的普通增量数字.用逗号动画