javascript循环遍历大全

1,109 阅读1分钟

前言 循环遍历在我们日常开发中是非常重要、使用频率非常高的。循环就是提供一种快速和简单的方式去做一些重复的是,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
}