JavaScript学习笔记:数组(八)_html/css_WEB-ITnose
很多时候需要累加数组项的得到一个值(比如说求和)。如果你碰到一个类似的问题,你想到的方法是什么呢?会不会和我一样,想到的就是使用 for 或 while 循环,对数组进行迭代,依次将他们的值加起来。比如:
var arr = [1,2,3,4,5,6];Array.prototype.sum = function (){ var sumResult = 0; for (var i = 0; i < this.length; i++) { sumResult += parseInt(this[i]); } return sumResult;}arr.sum(); // 21
或者
var arr = [1,2,3,4,5,6];Array.prototype.sum = function () { var sumResult = 0; var i = this.length; while (i--) { sumResult += parseInt(this[i]); } return sumResult;}arr.sum(); // 21
那他们是不是最好的方案呢?先来看看他们所耗时间。
// 测试for和while循环实现数组求和的性能var arr = [1,2,3,4,5,6];// for循环console.time("forLoop");Array.prototype.forLoop = function (){ for (var i = 0; i < 10000; i++) { var sumResult = 0; for (var j = 0; j < this.length; j++) { sumResult += parseInt(this[j]); } } return sumResult;}arr.forLoop();console.log('最终的值:' + arr.forLoop()); // 21console.timeEnd("forLoop"); // 54.965ms
再来看看 while 循环所用时间:
var arry = [1,2,3,4,5,6];console.time("whileLoop");Array.prototype.whileLoop = function () { for (var i = 0; i < 10000; i++) { var sumResult = 0; for (var j = 0; j < this.length; j++) { sumResult += parseInt(this[j]); } } return sumResult;}arry.whileLoop();console.log('最终的值:' + arry.whileLoop()); // 21console.timeEnd("whileLoop"); // 53.056ms
看看对比结果
循环类型 | 最终值(和) | 所费时间 |
---|---|---|
for | 21 | 54.965ms |
while | 21 | 53.056ms |
备注:数组 [1,2,3,4,5,6] 做了 10000 次循环的累加。
虽然上面使用 for 和 while 都能实现需要的效果,但在JavaScript中有没有更好的方案呢?回答是肯定的,在JavaScript中(ESMAScript 5)提供了另外两个数组的方法 reduce() 和 reduceRight() ,这两个数组会迭代数组的所有数组项,然后返回一个最终值。接下来的内容,主要来学习这两种方法。
reduce() 方法
reduce() 方法接收一个函数 callbackfn 作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。
语法
array.reduce(callbackfn,[initialValue])
reduce() 方法接收 callbackfn 函数,而这个函数包含四个参数:
function callbackfn(preValue,curValue,index,array){}
- preValue : 上一次调用回调返回的值,或者是提供的初始值(initialValue)
- curValue : 数组中当前被处理的数组项
- index : 当前数组项在数组中的索引值
- array : 调用 reduce() 方法的数组
而 initialValue 作为第一次调用 callbackfn 函数的第一个参数。
reduce() 方法为数组中的每一个元素依次执行回调函数 callbackfn ,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce() 的数组。
回调函数第一次执行时, preValue 和 curValue 可以是一个值,如果 initialValue 在调用 reduce() 时被提供,那么第一个 preValue 等于 initialValue ,并且 curValue 等于数组中的第一个值;如果 initialValue 未被提供,那么 preValue 等于数组中的第一个值,`curValue等于数组中的第二个值。
来看一个示例:
var arr = [0,1,2,3,4];arr.reduce(function (preValue,curValue,index,array) { return preValue + curValue;}); // 10
示例中的回调函数被执行四次,每次参数和返回的值如下:
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 0 | 1 | 1 | [0,1,2,3,4] | 1 |
第二次回调 | 1 | 2 | 2 | [0,1,2,3,4] | 3 |
第三次回调 | 3 | 3 | 3 | [0,1,2,3,4] | 6 |
第四次回调 | 6 | 4 | 4 | [0,1,2,3,4] | 10 |
上面的示例 reduce() 方法没有提供 initialValue 初始值,接下来再上面的示例中,稍作修改,提供一个初始值,这个值为 5 。这个时候 reduce() 方法会执行五次回调,每次参数和返回的值如下:
var arr = [0,1,2,3,4];arr.reduce(function (preValue,curValue,index,array) { return preValue + curValue;}, 5); //15
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 5 | 0 | 0 | [0,1,2,3,4] | 5 |
第二次回调 | 5 | 1 | 1 | [0,1,2,3,4] | 6 |
第三次回调 | 6 | 2 | 2 | [0,1,2,3,4] | 8 |
第四次回调 | 8 | 3 | 3 | [0,1,2,3,4] | 11 |
第五次回调 | 11 | 4 | 4 | [0,1,2,3,4] | 15 |
这样一来,不用多说,应该都知道,可以使用 reduce() 实现数组求和的功能。如:
var arr = [1,2,3,4,5,6];Array.prototype.sum = function (){ var sumResult = 0; return this.reduce(function (preValue, curValue) { return sumResult = preValue + curValue; }); return sumResult;}arr.sum(); // 21
回到文章的前面,来看看使用 reduce() 方法对数组求和,需要多少时间:
var arr = [1,2,3,4,5,6];console.time("ruduce");Array.prototype.ruduceSum = function (){ for (var i = 0; i < 10000; i++) { return this.reduce (function (preValue, curValue) { return preValue + curValue; }); }}arr.ruduceSum();console.log('最终的值:' + arr.ruduceSum()); // 21console.timeEnd("ruduce"); // 0.417ms
同时看看所费时间的对比:
循环类型 | 最终值(和) | 所费时间 |
---|---|---|
for | 21 | 54.965ms |
while | 21 | 53.056ms |
reduce | 21 | 0.417ms |
在Chrome浏览器下,每次执行的数据都会略有不同,但可以明显的看出 reduce() 对数组项求和所费时间是最短的。
reduceRight() 方法
reduceRight() 方法的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。
reduceRight() 首次调用回调函数 callbackfn 时, prevValue 和 curValue 可以是两个值之一。如果调用 reduceRight() 时提供了 initialValue 参数,则 prevValue 等于 initialValue , curValue 等于数组中的最后一个值。如果没有提供 initialValue 参数,则 prevValue 等于数组最后一个值, curValue 等于数组中倒数第二个值。
来看实例:
var arr = [0,1,2,3,4];arr.reduceRight(function (preValue,curValue,index,array) { return preValue + curValue;}); // 10
回调将会被调用四次,每次调用的参数及返回值如下:
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 4 | 3 | 3 | [0,1,2,3,4] | 7 |
第二次回调 | 7 | 2 | 2 | [0,1,2,3,4] | 9 |
第三次回调 | 9 | 1 | 1 | [0,1,2,3,4] | 10 |
第四次回调 | 10 | 0 | 0 | [0,1,2,3,4] | 10 |
如果提供一个初始值 initialValue 为 5 :
var arr = [0,1,2,3,4];arr.reduceRight(function (preValue,curValue,index,array) { return preValue + curValue;}, 5); // 15
回调将会被调用五次,每次调用的参数及返回的值如下:
preValue | curValue | index | array | 返回值 | |
---|---|---|---|---|---|
第一次回调 | 5 | 4 | 4 | [0,1,2,3,4] | 9 |
第二次回调 | 9 | 3 | 3 | [0,1,2,3,4] | 12 |
第三次回调 | 12 | 2 | 2 | [0,1,2,3,4] | 14 |
第四次回调 | 14 | 1 | 1 | [0,1,2,3,4] | 15 |
第五次回调 | 15 | 0 | 0 | [0,1,2,3,4] | 15 |
同样的,可以对一个数组求和,也可以使用 reduceRight() 方法:
var arr = [1,2,3,4,5,6];console.time("ruduceRight");Array.prototype.ruduceRightSum = function (){ for (var i = 0; i < 10000; i++) { return this.reduceRight (function (preValue, curValue) { return preValue + curValue; }); }}arr.ruduceRightSum();console.log('最终的值:' + arr.ruduceSum()); // 21console.timeEnd("ruduceRight"); // 5.725ms
总结
reduce() 和 reduceRight() 两个方法功能都是类似的,可以让数组调用一个回调函数 callbackfn 作为累加器。实际上根据这个回调函数,可以实现不同的功能,比如说,对数组项求合;将多个数组合并到一个数组等等。甚至配合数组其他的方法你还可以做更多功能的处理。如果感兴趣的话不仿尝试一二。
初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。
大漠
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

本文讨论了HTML&lt; Progress&gt;元素,其目的,样式和与&lt; meter&gt;元素。主要重点是使用&lt; progress&gt;为了完成任务和LT;仪表&gt;对于stati

本文讨论了html&lt; datalist&gt;元素,通过提供自动完整建议,改善用户体验并减少错误来增强表格。Character计数:159

本文讨论了HTML&lt; meter&gt;元素,用于在一个范围内显示标量或分数值及其在Web开发中的常见应用。它区分了&lt; meter&gt;从&lt; progress&gt;和前

本文讨论了使用HTML5表单验证属性,例如必需的,图案,最小,最大和长度限制,以直接在浏览器中验证用户输入。

本文讨论了视口元标签,这对于移动设备上的响应式Web设计至关重要。它解释了如何正确使用确保最佳的内容缩放和用户交互,而滥用可能会导致设计和可访问性问题。

本文讨论了&lt; iframe&gt;将外部内容嵌入网页,其常见用途,安全风险以及诸如对象标签和API等替代方案的目的。

GiteePages静态网站部署失败:404错误排查与解决在使用Gitee...
