写点什么

重学 JS | 数组遍历的 7 种方法及兼容性处理 (polyfill)

用户头像
梁龙先森
关注
发布于: 2020 年 12 月 28 日
重学JS | 数组遍历的7种方法及兼容性处理(polyfill)

数组相关文章:

数组去重的 7 种算法

找出数组中出现次数最多元素的 4 种算法

数组遍历的 7 种方法及兼容性处理 (polyfill)


数组的遍历在数组的所有操作中应该是最频繁的,这里总结下 7 中常见的遍历方法。同时,通过 polyfill 理解每个函数的内部实现。

1. 最原始的 for 循环

const arr = [1,2,3]for(let i=0;i<arr.length;i++){  console.log(arr[i])}
复制代码

2. 基于 forEach()函数的方法

const arr = [1,2,3]arr.forEach(function(element,index,array){	console.log(element)})
复制代码

forEach()函数是 ES5 中新增的特性,可能不兼容只支持低版本 JS 的浏览器,因此提供个pollyfill

Array.prototype.forEach = Array.prototype.forEach || function(fn,context){  // 通过for循环,在循环中判断this对象,即数组本身是否包含遍历的索引。  // 包含,则利用call()函数去调用回调函数,传入回调函数所需的参数。  if(typeof fn==='function'){    for(var k=0,length=this.length;k<length;k++){    	Object.prototype.hasOwnProperty.call(this,k) && fn.call(context,this[k],k,this)    }  }}
复制代码

3. 基于 map()函数的方法

map()在数据遍历中,将数组中的每个元素做处理,得到新的元素。需要注意的是回调函数需要通过return返回处理后的值,否则会返回undefined

const arr = [1,2,3]const arr1 = arr.map(function(element){	return element*2})console.log(arr1)  // [2,4,6]
复制代码

forEach()函数一样,map()同样需要提供polyfill

Array.prototype.map = Array.prototype.map || function(fn,context){	var arr = []  if(typeof fn==='function'){    for(var k=0,length=this.length;k<length;k++){  	  if(Object.prototype.hasOwnProperty.call(this,k)){    	   arr.push(fn.call(context,this[k],k,this))      }    }  }  return arr}
复制代码

4. 基于 filter()函数的方法

filter()函数用于过滤出满足条件的数据,返回一个新的数组,不会改变原来的数组。

const arr = [1,2,3,4]const filterFn = function(element){	return element>2}const arr1 = arr.filter(filterFn)  // [3,4]
复制代码

polyfill代码如下:

Array.prototype.filter = Array.prototype.filter || function(fn,context){	var arr = [];  if(typeof fn==='function'){    for(var k=0,length=this.length;k<length;k++){  	  if(Object.prototype.hasOwnProperty.call(this,k)){        // 通过判断返回值是否为true来决定是否push到新数组        fn.call(context,this[k],k,this) && arr.push(this[k])      }    }  }  return arr}
复制代码

5. 基于 some()和 every()函数的方法

some()函数只要数组中某个元素满足条件就返回true,而every()函数需要数组中的每个元素都满足条件时才返回true

function isBig(element,index,array){	return element>2}
const passed1 = [1,2,3,4].some(isBig) // trueconst passed2 = [1,2,3,4].every(isBig) // false
复制代码

some()函数的pollyfill如下:

Array.prototype.some = Array.prototype.some || function(fn,context){  var passed = false  if(typeof fn==='function'){  	for(var k=0,length=this.length;k<length;k++){    	if(passed===true) break; // 有返回值true,直接跳出循环      passed = Object.prototype.hasOwnProperty.call(this,k)?        !! fn.call(context,this[k],k,this):passed    }  }   return passed}
复制代码

every()函数的pollyfill如下:

Array.prototype.every = Array.prototype.every || function(fn,context){  var passed = true  if(typeof fn==='function'){  	for(var k=0,length=this.length;k<length;k++){    	if(passed===false) break; // 有返回值false,直接跳出循环      passed = Object.prototype.hasOwnProperty.call(this,k)?        !! fn.call(context,this[k],k,this):passed    }  }   return passed}
复制代码

6. 基于 reduce()函数的方法

reduce()函数主要作用是做累加处理,即接收一个函数作为累加器。

arr.reduce(callback[,initialValue]);

callback 接收四个参数:accumulatorcurrentValuecurrentIndexarray

initialValue:作为 callback 的第一个参数值,若未设置,则默认使用数组的第一个元素值。

accumulator: 表示上一次调用累加器的返回值,或设置的initialValue

let arr = [1,2,3]let add = function(accumulator,currentValue){	return accumulator+currentValue}let sum = arr.reduce(add,0)  // 6
复制代码

reduce()函数的 polyfill 如下:

Array.prototype.reduce = Array.prototype.reduce || function(callback,initialValue){  var previous = initialValue,k = 0, length = this.length;  if(typeof initialValue === 'undefined'){  	previous = this[0]    k = 1  }  if(typeof callback === 'function'){  	for(k;k<length;k++){    	this.hasOwnProperty(k) && (previous = callback(previous,this[k],k,this))    }  }  return previous}
复制代码

7. 基于 find()函数的方法

find()函数用于数组遍历的过程中,找到第一个满足条件的元素值时,则直接返回该元素值;如果都不满足条件,则返回undefined

let arr = [1,2,3]let value = arr.find(function(element,index,array){	return element>2})  // 3
复制代码

find()函数的 polyfill 如下:

Array.prototype.find = Array.prototype.find || function(fn,context){	if(typeof fn==='function'){  	for(var k = 0,length = this.length;k < length;k++){    	if(fn.call(context,this[k],k,this)){      	return this[k]      }    }  }  return undefined}
复制代码

8. 总结

至此我们完成了 7 个与函数遍历相关的方法,以及它们的polyfill实现。

发布于: 2020 年 12 月 28 日阅读数: 40
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
重学JS | 数组遍历的7种方法及兼容性处理(polyfill)