Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么Array.prototype.reduce没有thisObject参数?_Javascript_Ecmascript 5 - Fatal编程技术网

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=thisresult
的顶部添加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的问题的。