繁体   English   中英

为什么使用.reduce代替reduce()? 用JavaScript展平数组的数组

[英]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 ,但是为什么呢?

这是对有用的评论的回答,但不包括原始问题。

  • 我的问题是第一个程序。 由于它使用arrays.reduce,reduce将是数组的方法,所以我不确定为什么reduce是数组的方法。 原因可能在JavaScript的设计决策中? 谢谢@cookie Monster,发表评论!

这是与我的问题相关的程序-

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()函数相比,这种面向对象的方法具有以下优点:

  1. 它与语言中其他地方使用的面向对象的原理一致。
  2. 通过使用array.reduce()在特定array上调用.reduce()函数很方便,并且从语法上可以明显array.reduce()它在哪个数组上进行操作。
  3. 所有数组操作都作为Array对象上的方法进行分组,从而使API定义更加易于记录。
  4. 如果尝试执行obj.reduce() (在非数组上调用它),则将立即收到有关未定义的.reduce()方法的运行时错误。
  5. 在全局范围内不占用额外的空间(例如,没有定义其他的全局符号-减少了意外覆盖或与其他代码冲突的机会)。

如果您想知道为什么有人曾经使用全局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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM