[英]Why is .reduce used instead of reduce()? In flattening an array of arrays with JavaScript
此示例来自http://eloquentjavascript.net/code/#5.1 。 我的问题是第一个要点细节。 其他可能是有用的细节,但是附加的; 另请参阅第一个简短程序,以了解我的问题。
arrays.reduce()
代替reduce(arrays())
。 我知道他们的与arrays.reduce
,但是为什么呢? 这是对有用的评论的回答,但不包括原始问题。
这是与我的问题相关的程序-
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
return flat.concat(current);
}, []));
// → [1, 2, 3, 4, 5, 6]
以下详细信息是附加的,但可能(也可能不会)有用:
我知道使用结尾处的[]
是因为它是reduce函数中的开始参数,因此其他数组将添加到该空数组中。 我知道.concat
会将两个+
的字符串与字符串放在一起,但对于数组。 即使标准功能,reduce函数的外观也如下所示:
function reduce(array, combine, start){
var current = start;
for(var i = 0; i < array.length; i++)
current = combine(current, array[i]);
return current;
}
如果有帮助的话,他们的其他例子之一展示了我使用单个数组的方式。 它看起来像:
console.log(reduce([1, 2, 3, 4], function(a, b){
return a + b;
}, 0));
// 10
谢谢! :)
JavaScript受/受Lisp的方言语言Scheme的影响。 在Scheme中, 高阶函数是语言的关键组成部分/功能。 实际上, reduce
函数与Scheme中的fold
函数非常相似。 对于JavaScript中的reduce
函数,该语言的创建者注意到程序员经常需要以某种方式遍历数组,并为程序员提供了更高阶的函数,他们可以在其中传递函数来指定他们想要如何操作数组。数据。 具有高阶函数可以使程序员抽象冗余代码,从而创建更短,更干净,更具可读性的代码。
您可以使用JavaScript中的reduce
函数执行除扁平化列表以外的许多操作。 看这里的例子。
在面向对象的设计中,一个指导原则是创建或声明对象,并且这些对象上具有针对该特定类型的对象进行操作的一系列方法。 由于Javascript是一种面向对象的语言,因此内置函数遵循许多面向对象的原理。
.reduce()
是仅在数组上运行的函数。 没有数组就没有用。 因此,在面向对象的设计范例中,将.reduce()
函数作为方法放置在Array
对象上是完全有意义的。
与全局reduce()
函数相比,这种面向对象的方法具有以下优点:
array.reduce()
在特定array
上调用.reduce()
函数很方便,并且从语法上可以明显array.reduce()
它在哪个数组上进行操作。 Array
对象上的方法进行分组,从而使API定义更加易于记录。 obj.reduce()
(在非数组上调用它),则将立即收到有关未定义的.reduce()
方法的运行时错误。 如果您想知道为什么有人曾经使用全局reduce()
,那么您需要了解一些有关Javascript演变的历史。 在ES5之前(或针对运行尚未实现ES5的浏览器(如IE8)的用户),Javascript在Array
对象上没有内置的.reduce()
方法。 但是,一些熟悉其他语言的有用迭代功能的开发人员希望在自己的Javascript或自己的Javascript框架中使用它。
当您想向现有内置对象(如Javascript中的Array
添加某些功能时,通常有两种选择。 您可以将方法添加到原型(以面向对象的方式),也可以创建将Array
作为其第一个参数的全局函数。
特别是对于Array
对象,向Array
原型添加可迭代方法存在一些潜在的问题。 这是因为,如果有任何代码执行数组的这种类型的迭代(迭代数组的一种不好的方法,但是仍然由许多人完成):
for (var prop in array)
它们不仅会迭代数组的元素,而且还会迭代数组的所有可迭代属性。 如果使用这种语法将新方法分配给原型:
Array.prototype.myMethod = function() {}
然后,此新方法最终将使用for (var prop in array)
语法for (var prop in array)
迭代,并且通常会引起问题。
因此,与其在原型上添加新的方法,不如选择一种更安全的替代方法,即仅使用全局函数并避免出现此问题。
从ES 5.1开始,有一种方法可以使用Object.defineProperty()
将不可迭代的方法添加到对象或原型,因此对于较新的浏览器,现在可以将方法添加到原型中,而不会遇到上述问题。 但是,如果您想支持较旧的浏览器(如IE8)并使用reduce()
类型的功能,则仍然会遇到这些古老的限制。
因此,即使全局的reduce()
不太面向对象,并且在Javascript中通常并不理想,但是出于合法的安全性/互操作性原因,一些较旧的代码还是选择了这种方式。 幸运的是,随着旧版本IE的使用率下降,我们正在走这条路(感谢微软放弃XP支持,以最终加速旧版本IE的淘汰)。 而且较新的浏览器已经包含内置的array.reduce()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.