前言 循环遍历在我们日常开发中是非常重要、使用频率非常高的。循环就是提供一种快速和简单的方式去做一些重复的是,javascript中提供了许多循环语句,如经常用到的for循环、forEach遍历等等
需要注意的是for和forEach都对数组进行遍历操作,但是for是javascript原生语句,而forEach是数组的原型方法,这两者是有区别的,下面内容会讲解到
本篇文章就来罗列学习,javascript中所有的循环遍历方法。
for语句
for是一个循环语句,一个for循环会一直重复执行,直到指定的循环条件为false
,常用来遍历数组。for循环包含三个可选表达式,它们都被包裹在圆括号中,以分号隔开。
for(var i=0;i<5;i++){
// 执行代码
}
while语句
while是一个语句,在条件表达式为真时,循环执行指定的代码段,直到表达式不为真时结束。它属于前测试循环语句,即在执行循环体内的代码段之前先看条件表达式的结果是否为真
let arr = [1,2,3,4]
while(arr.length){
arr.splice(0,1)
console.log(arr)
}
如上代码例子,循环判断数组arr
的长度,从数组中逐个删除数组元素直至将其变为空数组
do-while语句
do while是一个语句,它包含一个条件表达式和一个循环体,与while不同,它属于后测试循环语句,会先执行一次循环体内的代码,然后再执行指定的条件表达式,即循环体内代码至少会执行一次
do{
i++
}while(i<5)
for...in语句
for...in语句是一种精准的迭代语句,以任意顺序遍历一个对象的除Symbol
以外的可枚举属性,它就是为遍历对象属性而存在的。
虽然它也可以用来迭代数组,迭代数组时枚举的是数组元素的下标,但是不推荐把它和数组放在一起使用
let obj = {
name:'王',
age:23,
job:'测试'
}
for(const k in obj){
console.log(k)
}
for of
for...of语句在可迭代对象上创建一个迭代循环,调用自定义迭代钩子,为每个不同属性的值执行语句。上面提到了数组不可和for...in
一起使用,那么要迭代数组就可以使用for...of
,数组是可迭代对象,for...of
就是在可迭代对象上创建迭代循环。可迭代对象还包括Map、Set、String、arguments等
let arr = [1,2,3,4]
for(k of arr){
console.log(k)
}
for语句和while语句的区别
for循环和while循环执行某个重复操作,但是它们的使用场景还是不同的。比如上文提到的逐个删除数组中的元素,直至为空。使用while语句其条件表达式判断数组长度,循环体中逐个splice出去元素项,但是如果按照这个思路使用for循环实现就会出现问题
for语句是以变量的变化来控制循环进程的,整个循环流程是计划好的,循环次数、循环状态等信息都是确定的,也就是说for语句是确定循环次数的
Array.prototype.forEach()
forEach是挂载在数组原型上的方法,它可以对数组的每项进行遍历并执行给定的函数,接收一个callback回调,它的返回值总是undefined。
- forEach遍历的范围在第一次调用callback前就已经确定了,调用forEach后添加到数组中的项不会被callback访问到,已删除的项不会被遍历到
- forEach不可以中止或跳出循环
实现forEach
Array.prototype._forEach = function(callback){
for(var i=0;i<this.length;i++){
if(this[i]){
callback(this[i],i,this)
}
}
}
Array.prototype.map()
遍历数组,数组中的每一项调用其给定的函数生成一个新的数组
- map方法给原数组中的每一项按顺序调用一次callback函数
- 生成一个新的数组,新数组的每项是原数组每项调用callback后的值
- map不会改变原数组
实现map
Array.prototype._map = function(callback){
let result = [];
for(var i=0;i<this.length;i++){
result.push(callback(this[i],i,this))
}
return result
}
Array.prototype.every()
every()
方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值,都满足则返回true,有一个不满足都会返回false
- every遍历的元素范围在第一次调用callback前就已经确定了
- every遍历不会改变原数组
实现every
Array.prototype._every = function(callback){
let res = true
for(var i=0;i<this.length;i++){
if(!callback(this[i])){
res = false
break
}
}
return res
}
Array.prototype.some()
some()
方法测试数组中是否有至少一项通过指定函数的测试,返回一个布尔值,如果有至少一项通过则返回true,否则返回false
- 与
every
不同,every全部项满足则返回true,some只要有一项满足就返回true - 调用some不会改变原数组
实现some
Array.prototype._some = function(callback){
let result = false
for(var i=0;i<this.length;i++){
if(callback(this[i],i,this)){
result = true
break
}
}
return result
}
Array.prototype.filter()
filter()
方法返回一个新数组, 其包含通过所提供函数实现的测试的所有元素。
- filter不会改变原数组,返回一个新的数组
- filter遍历的元素范围在第一次调用callback前就已经确定
实现filter
Array.prototype._filter = function(callback){
let res = []
for(var i=0;i<this.length;i++){
if(callback(this[i],i,this)){
res.push(this[i])
}
}
return res
}
Array.prototype.find()
find()
方法返回数组中满足条件的第一个元素的值,否则返回undefined
- find方法对数组中的每一项元素执行callback函数,返回第一个为true的元素值
- find不会改变原数组
实现find
Array.prototype._find = function(callback){
let res = undefined
for(var i=0;i<this.length;i++){
if(callback(this[i],i,this)){
res = this[i]
break;
}
}
return res
}
Array.prototype.findIndex()
find()
方法返回数组中满足条件的第一个元素的索引,否则返回-1
实现findIndex
Array.prototype._findIndex = function(callback){
let result = -1
for(var i=0;i<this.length;i++){
if(callback(this[i],i,this)){
result = i
break
}
}
return result
}
Array.prototype.reduce()
reduce()
方法对数组中的每一项元素执行一个reducer函数,将其结果汇总为单个返回值
它接收两个参数,一个reducer函数提供给数组每一项调用,一个可选初始值参数
举个栗子 累加计算
const arr = [1,2,3,4]
const sum = arr.reduce((accumator,currVal) => {
return accumator+currVal
},0)
用于vue中属性值链式查找值
在使用vue的过程中,我们经常会使用这种写法{{person.info.height}}
,这样可以将height的值渲染在dom中,这里借用到了reduce的方法特性实现链式调用。 如下有个obj对象,需要获取最内层height属性的值。
字符串person.info.height
分割成数组,数组调用reduce方法,第二个参数传入obj对象作为第一次的初始值
const obj = {
person:{
name:'王二小',
info:{
height:170
}
}
}
const str = 'person.info.height'
const res = str.split('.').reduce((nObj,curr) => {
console.log(nObj,curr)
return nObj[curr]
},obj)
// 最终打印出 170
实现reduce
Array.prototype._reduce = function(callback,initialVal){
var o = Object(this)
var len = o.length
var k = 0;
var value;
if(arguments.length >= 2){
value = arguments[1]
}else{
value = o[k++]
}
for(;k<len;k++){
value = callback(value,o[k])
}
return value
}