js-各种for循环分析

在我们开发过中使用最多的无外乎就是三大结构:顺序结构、选择结构、循环结构。在JavaScript中的循环结构多种多样,如最常见的for循坏、forEach循环、for…in循环、for…of循环;当然还有while等其它循环,但是此文只讨论各种for循环,分析它们的优势及局限性。

1. 普通for循环

for循环是最普通也是使用频率比较高的

let array = [3,5,2,1]
for (let i = 0; i < array.length; i++) {
    console.log(array[i]) // 3 5 2 1
}

相信每个开发者都是用过,所以不用过多说明;需要注意的是for括号中有三部分,中间部分是一个表达式,返回true或false,以此判断是否继续执行内部代码。如果出现如下代码也不要惊讶

// 表达式部分为1,所以始终为true,会一直执行下去,直到i === 5才中断
for (let i = 0; 1; i++) {
    console.log(i) // 0 1 2 3 4 5
    if (i === 5) break
}

局限:for循环作为最早的循环结构代码相对而言有点冗余

2. forEach

forEach是为数组循环而专门设计的

let array = [3,5,2,1]
// item: 当前值, index:当前值索引
array.forEach((item, index) => {
    console.log(item); // 3 5 2 1
    console.log(index); // 0 1 2 3 
    if (item === 5) return
})

上述代码有什么问题,没错,为什么判断了item === 5return不起作用

局限:在forEach中return不起作用,并且break会报非法语句

3. for…in

for…in是为遍历对象而设计的,可以遍历对象的key;同样可以遍历数组,因为数组严格只是键名比较特殊的对象。

const obj = {
    name: 'lisi',
    age: 13,
}

for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
        console.log(key) // name age
        console.log(obj[key]) //lisi 13
    }
}

如果没有判断Object.hasOwnProperty.call(obj, key)则同时会从原型上获取属性

function Person(name, age) {
    this.name = name
    this.age = age
}

Person.prototype.friend = 'zs'

let p = new Person('lisi', 13)

for (const key in p) {
    console.log(p[key]) // lisi 13 zs
}

使用for…in遍历数组

let arr = [3,5,2,1]
for (const key in arr) {
    console.log(typeof key) // string
    console.log(arr[key]) // 3 5 2 1
}

局限:for…in遍历对象会获取原型上的属性;for…in遍历数组的索引值是string类型的;不能保证遍历属性的顺序

4. for…of

es6新增的循环结构,用于代替forEach以及for…in。for…of用于遍历可迭代数据结构,例如:数组、字符串、集合、map映射。

let arr = [3,5,2,1]
for (const iterator of arr) {
    console.log(iterator) // 3 5 2 1
}

普通对象不可迭代

let obj = {
    name: 'lisi',
    age: 13,
}
for (const iterator of obj) {
    console.log(iterator) // obj is not iterable (obj不可迭代)
}

// 类数组对象可以通过Array.from处理,而普通对象只能自定义迭代器
// 通过下面的自定义迭代器
obj[Symbol.iterator] = function () {
    // 获取当前对象的所有键数组
    var keys = Object.keys(this);
    var count = 0;
    return {
        next() {
            // 如果当前count小于键数组长度,说明还没有遍历完
            if (count < keys.length) {
                // 返回value
                return { value: obj[keys[count++]], done: false };
            } else {
                return { value: undefined, done: true };
            }
        }
    }
};

for…of不能获取遍历元素的索引,必须通过变通方式

let arr = [3,5,2,1]
// 结构赋值
for (const [index, iterator] of new Map(arr.map(( item, i ) => [i, item]))) {
    console.log(index) // 0 1 2 3
    console.log(iterator) // 3 5 2 1
}

局限:for…of无法打印索引;for…of无法遍历普通对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值