ES5规范中为为数组定了5个迭代方法和2个归并方法,日常工作我们使用还是很普遍的,现代浏览器对其都已支持,文章将对这些方法的实现进行详细的阐述,算是对旧浏览器的polyfill吧。
迭代方法
数组的迭代方法,每个方法都会接受两个参数:(1)要在每一项上运行的函数(2)运行该函数的作用域——影响this的值(可选)。传入方法中的函数会接受三个参数:(1)数组每项的值(2)该项在数组中的位置(3)数组对象本身。
5种迭代方法的作用如下:
every():对数组中的每一项执行给定函数,如果每一项执行后返回true,则返回true。
filter():对数组中的每一项执行给定函数,返回改函数会返回true的项组成的数组。
forEach():对数组中的每一项执行给定函数,没有返回值。
map():对数组中的每一项执行给定函数,返回每次调用函数的结果组成数组。
some():对数组中的每一项执行给定函数,如果该函数对数组中任一项都返回true,则返回true。
map方法
if(!Array.prototype.map){
Array.prototype.map = function(callback, context){
if( this == null ){
throw new TypeError("this is null or undefined")
}
// callback不为函数时,抛出异常
if( typeof(callback) != "function" ){
throw new TypeError( callback + "is not a function" )
}
var retArr = [], // 返回的数组
len = this.length; // 数组的长度
for(var i=0; i
filter方法
if(!Array.prototype.filter){
Array.prototype.filter = function(callback, context){
if( this == null ){
throw new TypeError("this is null or undefined")
}
// callback不为函数时,抛出异常
if( typeof(callback) != "function" ){
throw new TypeError( callback + "is not a function" )
}
var retArr = [], // 返回的数组
len = this.length, // 数组的长度
context = arguments.length >= 2 ? arguments[1] : null, // 运行函数的作用域
boolean; // 临时变量
for(var i=0; i
归并方法
数组还有两个归并的方法:reduce和reduceRight。这两个方法会迭代数组的所有项,最终返回一个迭代的最后值。reduce方法从数组的第一项开始迭代,reduceRight则从数组的最后一项开始。两个方法接受参数相同,都是两个参数:一个是在在每项上调用的函数以及迭代的初始值(可选)。下面,我们对reduce方法的实现进行详解。
Array.prototype.Reduce = function(callback, intialValue){
if( this == null ){
throw new TypeError("this is null or undefined")
}
// callback不为函数时,抛出异常
if( typeof(callback) != "function" ){
throw new TypeError( callback + "is not a function" )
}
var retValue, // 返回值
len = this.length,
i = 0;
// 初始值设置
if(arguments.length >= 2){
retValue = arguments[1];
}else {
retValue = this[i++]; // i+1,当没有有初始值时,初始值为数组第一个值
}
while(i
迭代方法与ES6中Set的搭配使用
ES6规范中Set数据结构,类似于数组,但其中的值全都是唯一的。搭配数组的迭代方法,我们能够快速方便地实现两个或多个数组的交、并、差集。
var a = new Set([1,3,4,'33',true,7]),
b = new Set([1,7,4,'44',false]);
/* 并集 */
var union = Array.from(new Set([...a, ...b])); // 并集:1,3,4,33,true,7,44,false
/* 交集 */
var intersect = [...a].filter( item => b.has(item) ); // 交集:1,4,7
/* 差集 */
var diff = union.filter( item => !((new Set(intersect)).has(item)) ) // 差集:3,33,true,44,false
参考
MDN web docs
ECMAScript 6入门