一篇文章理解JS中几种常用循环方法及原理

1.for循环

for循环是最基础以及最常用的循环方法,模板:for(表达式1;表达式2;表达式3)

包含了for(i in obj)for(item of obj)的方法。

for 语句用于创建一个循环,它包含了三个可选的表达式,这三个表达式被包围在圆括号之中,使用分号分隔,后跟一个用于在循环中执行的语句(通常是一个块语句)。
let str='';
​
for (let i=0; i<9; i++) {
  str = str+i;
}
​
console.log(str);
// 答: "012345678"

break和continue:

for 循环中使用 breakcontinue 语句 (终止 和 跳过 本次循环)

// break 案例
for(let i=1; i<=10; i++){
    if(i=3){
        break; //跳出本次循环,执行循环之后的语句,整个循环终止
    }
    console.log(i)
}
// continue 案例
for(let i=1; i<=10; i++){
    if(i==3||i==7||i==9){
        continue; //中断循环中的迭代,然后继续循环中下一个迭代
    }
}

for...of 和 for...in:

for...of语句可迭代对象(Array,Map,Set,String,TypedArray,arguments对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

const array= ['a','b','c']

for(const item of array){
    console.log(item)
}
//答:'a' 'b' 'c'
// 语法:
for (var variable of iterable) {
//statements
}
//variable 在每次迭代中,将不同属性的值分配给变量。
//iterable 被迭代枚举其属性的对象。

for...in语句可以任意顺序遍历一个对象的除 Symbol以外的可枚举属性

var obj= {a:1,b:2,c:3}
for(var prop in obj){
    console.log('obj.'+prop+'='+obj[prop])
}
//答:'obj.a=1' 'obj.b=2' 'obj.c=3'
//语法:
for(var variable in object){
//statement
}
//variable 在每次迭代时,variable会被赋值为不同属性名
// object 非Symbol类型的可枚举属性被迭代的对象

迭代自身的属性:

如果值需要对象自身而不是原型上的属性,可以使用Object.getOwnPropertyNames(obj)obj.hasOwnProperty()来确定某属性是否对象本身的属性。

2.forEach循环

forEach()方法对数组的每个元素执行一次给定的函数,返回一个回调函数。
// 语法 
arr.forEach(callbackFn(currentValue, index, arr))
//callback 必需。 数组中每个元素需要调用的函数。
// currentValue 必需。当前元素。
// index 可选。当前元素的索引值。
// arr  可选。当前元素所属的数组对象。
let arr= [1,2,3,4]
let sum=0
arr.forEach(function(value,index,arr){
    array[index] ==value//结果为true
    sum+=value
})
console.log(sum) //结果为10

forEach被调用时,不会修改原数组(callback函数在被调用时可能会改变原数组)

forEach跳出循环:

var arr= [1,2,3,4,5,6]
arr.forEach((item)=>{
    if(item===3){
        return
    }
    console.log(item)
})
//答:1,2,4,5,6

forEach终止:(抛出异常方式)

var arr= [1,2,3,4,5,6]
try{
    arr.forEach((item)=>{
        if(item===3){
            throw new Error('End Loop')
        }
        console.log(item)
    })
}catch(e){
    if(e.message==='End Loop') throw e
}
// 答: 1 2
​

3.map循环

map是“映射”的意思,用法与forEach相似。与forEach不同的是,map循环方法会返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

var arr= [1,2,3]
var brr=arr.map(function(item,index){
    return item*2
})
console.log(arr) //[1,2,3]
console.log(brr) //[2,4,6]
​
因为map返回的是一个新数组,这样的优点在于可以复合使用(composition)(map(),filter(),reduce())组合完成复杂操作。
let arr= [1,2,3,4,5]
let arr1=arr.map(num=>num*2).filter(num=>num>5)
console.log(arr1)
// 答: [6,8,10]

map 和 forEach总结:

  • 能使用forEach做到的,map()都可以做到,反过来一样。

  • map()会分配内存空间存储新数据组并返回,forEach()不会返回数据。

  • forEach()允许callback更改原始数组的元素。map()返回新数组。

4.filter循环

filter用于对数组进行过滤,得到符合条件的新数组。

filter()不会对空数组进行检测;不会改变原数组。

//语法:
array.filter(function(currentValue,index,arr), thisValue)
// function(currentValue, index,arr) 必须。函数,数组中的每个元素都会执行这个函数
// currentValue 必须。当前元素的值
// index 可选。当前元素的索引值
// arr  可选。当前元素属于的数组对象
// thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"
let nums= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
let res=nums.filter((num) => {
  return num>5;
});
 
console.log(res);  // [6, 7, 8, 9, 10]
​

5.findIndex循环

findIndex方法常用来查找数组中满足条件的第一项元素的下标。 返回符合测试条件的第一个数组元素索引,如果没有符合条件的则返回 -1。

//语法:
array.findIndex(function(currentValue, index, arr), thisValue)
// function(currentValue, index,arr) 必须。数组每个元素需要执行的函数。
// currentValue 必需。当前元素
// index 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象
// thisValue    可选。 传递给函数的值一般用 "this" 值,如果这个参数为空, "undefined" 会传递给 "this" 值
const arr= [1, 2, 3, 4, 5, 3, 3, 2, 4, 5 ]
let index=arr.findIndex(item=> {
    return item>2
})
console.log(index) // 2
​

6.find循环

find()方法用于查找数组中符合条件的第一个元素,如果没有符合条件的元素,则返回undefined。

//语法:
array.find(function(currentValue, index, arr), thisValue)
// function(currentValue, index,arr) 必须。数组每个元素需要执行的函数。
// currentValue 必需。当前元素// index 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象
// thisValue  可选。 传递给函数的值一般用 "this" 值,如果这个参数为空, "undefined" 会传递给 "this" 值
let arr= [1, 2, 3, 4, 5];
let num=arr.find(item=> {
    return item>1
});
console.log(num)  //2

7.some循环

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

some() 方法会依次循环遍历数组:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。

  • 如果没有满足条件的元素,则返回false。

注意: some() 不会对空数组进行检测, some() 不会改变原始数组。

//语法:
array.some(function(currentValue, index, arr), thisValue)
// function(currentValue, index,arr) 必须。数组每个元素需要执行的函数。
// currentValue 必需。当前元素// index 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象
// thisValue  可选。 传递给函数的值一般用 "this" 值,如果这个参数为空, "undefined" 会传递给 "this" 值

let data= ['1','2','3']
let res = data.some(function(item){
    return item==='1'// true
})
console.log(res)//true
​

8.every循环

与some()方法相反every() 方法用于检测数组所有元素是否都符合指定条件(函数提供)。every() 方法使用指定函数检测数组中的所有元素:

  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。

  • 如果所有元素都满足条件,则返回 true。

注意: every() 不会对空数组进行检测,every() 不会改变原始数组。

//语法:
array.every(function(currentValue, index, arr), thisValue)
// function(currentValue, index,arr) 必须。数组每个元素需要执行的函数。
// currentValue 必需。当前元素// index 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象
// thisValue  可选。 传递给函数的值一般用 "this" 值,如果这个参数为空, "undefined" 会传递给 "this" 值

let data=['1','2','3']
let result=data.every(function(item){
    return item==='1'
})
console.log(result) // false

9.Object.keys循环

Object.keys()用于获得由对象属性名组成的数组

Object.keys() 结合 forEach() 遍历对象

var obj= {
    name: "lokka",
    age: 18,
    address: "beijing",
    1: "ok",
    _:"yes"
}
​
Object.keys(obj).forEach(function(i) {
    console.log(i, obj[i]);
})
​
// 1 ok
// name lokka
// age 18
// address beijing
// _ yes

思考:为什么不直接使用for in呢?

原因:从性能上考虑,for in会遍历整个原型链,这个可能不是你想要的结果,你可能只希望遍历这个对象本身的属性,从性能上来说Object.keys()会更优先。在一些eslint的规则中也默认禁用了for in循环。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.怪兽

希望大家能够多多支持,我会继续

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值