Javascript 为什么Array.prototype.reduce没有thisObject参数?
诸如Javascript 为什么Array.prototype.reduce没有thisObject参数?,javascript,ecmascript-5,Javascript,Ecmascript 5,诸如forEach之类的Javascript数组方法有一个thisArg参数,该参数用作调用回调的上下文: array.forEach(callback[, thisArg]) 正如每个,一些,过滤器和映射一样。但是,reduce和reduceRight没有这样的参数。是有什么特别的原因,还是没有必要 例如,考虑以下功能实现:使用还原> < /> >: function compose () { var fns = [].slice.call(arguments,0); ret
forEach
之类的Javascript数组方法有一个thisArg
参数,该参数用作调用回调的上下文:
array.forEach(callback[, thisArg])
正如每个
,一些
,过滤器
和映射
一样。但是,reduce
和reduceRight
没有这样的参数。是有什么特别的原因,还是没有必要
例如,考虑以下功能实现:使用<代码>还原> < /> >:
function compose () {
var fns = [].slice.call(arguments,0);
return function result() {
return fns.reduceRight(
function (prev,cur){
return [cur.apply(this,prev)];
},
arguments
)[0];
};
}
我想让它“意识到这一点”,以便在调用compose
返回的函数的上下文中调用正在编写的函数。目前,它们似乎是在全局对象的上下文中调用的。我可以做旧的var self=this在函数result
的顶部添加code>,并将其作为cur.apply
调用的第一个参数,我当前在这里有this
,但是如果reduce
接受了thisArg
参数,则这是不必要的
我是否在这里遗漏了一些东西,以及reduce
中是否有什么东西使它变得不必要或无用
更新
@是的,我想到了。我决不会批评API的设计,但是reduce
的签名对我来说似乎有点奇怪。第二个可选参数的功能不同于普通可选参数,后者通常只有一个默认值;相反,它的存在或不存在会改变行为,本质上是基于签名(参数计数)重载函数。当缺少第二个参数时,数组的第一个元素将成为起始值,对回调函数的第一个调用将针对第二个值。在我看来,通过简单地调用
array.slice(1).reduce(fn,array[0])
而不是为省略第二个参数的情况建立特殊规则,这反过来,如果您的假设是正确的,也使得基本上不可能找出在哪里指定thisArg
参数。再说一遍,我相信在规范被讨论的过程中,这些问题已经被讨论过了,并且可能有很好的理由使用这种方法。在您在答案中找到的Es讨论邮件列表上
具有回调的其他方法采用“thisArg”,并不是因为它是
需要,甚至有用,但为了兼容性,因为它们已经做到了
在提供这些功能的现有实现中
由于reduce
(Right
)已经包含了两个功能(请参见),这两个功能在纯语言中是有区别的(例如在Haskell中命名为foldl
和foldl1
)。引用:
这意味着reduce接受一个回调参数和两个可选参数:thisObject和init。哪一个应该先来?更常见的可能是init,但是您可以将回调arg与“thisObject”arg分开,这可能还可以。多个可选参数在这种情况下有点混乱
或者,我们可以消除额外的“thisObject”参数,因为人们总是可以[使用绑定]
我不认为这是一个大问题,因为这些函数的高阶函数通常与lamdba函数表达式一起使用(就像在您的示例中)。当然有点矛盾,但我们可以接受。想象一下备选方案:
array.reduce(callback[, initialValue[, thisArg]])
无法真正使用,我们无法真正确定“”,因为这意味着参数.length<2
-我们也可以按字面意思传递未定义的。这意味着
array.reduce(callback[, thisArg[, initialValue]])
这很难看,因为如果我们只需要一个初始值,我们总是需要将null
或一些东西传递给thisArg
您已经注意到,在您对Kangax的评论中(“第二个可选参数的功能不同于普通可选参数,[…]它的存在或不存在会改变行为”),但我不能支持您的说法
只需调用array.slice(1).reduce(fn,array[0])
因为a)不能使用复杂(链式)表达式而不是数组变量,b)很麻烦。您可以始终使用此方法:
array.reduce(callback.bind(context), initialValue);
。。。为了将特定的上下文附加到回调函数。可能是因为reduce
中的第二个参数是初始值,您需要使用reduceRight
执行此操作吗?我认为您可以在反向
d数组上使用forEach
轻松实现这一点。编辑:我想我的观点是,您不想减少函数数组,而只是通过函数运行一组输入。@tJener当然可以使用forEach(如下划线.js所示),但我发现使用reduce/Right.Nice搜索结果有一定的优雅性,然而,我发现来自该线程的其他邮件在该线程发布时(2009年3月)更加相关,EcmaScript 5非常稳定,只进行了编辑性修改。正如我们今天所知道的,JavaScript和任何rational设计都是在2008年底解决的。我就是这样读OP的问题的。