1.ES5 与 ES6 遍历数组的不同方法

ES5 与 ES6 遍历数组的不同方法

for ... of循环可以代替数组实例的forEach方法。

const arr = ['red', 'green', 'blue'];

arr.forEach(function (element, index) {
  console.log(element); // red green blue
  console.log(index);   // 0 1 2
});

for ... of(重头戏)

for...of循环相比其他几种做法,有一些显著的优点。

for (let val of [1,2,3]) {
  console.log(val);
}
    // 1,2,3
  • 不同于forEach方法,它可以与break、continue和return配合使用。
  • 提供了遍历所有数据结构的统一操作接口。

示例

迭代数组

let iterable = [10, 20, 30];

for (let value of iterable) {
    value += 1;
    console.log(value);
}
// 11
// 21
// 31

迭代String

let iterable = "boo";

for (let value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

迭代Map

let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (let entry of iterable) {
  console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]

for (let [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3

迭代Set

let iterable = new Set([1, 1, 2, 2, 3, 3]);

for (let value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

for of无法循环遍历对象

 for in 会遍历自定义属性,for of不会

const arr = ['nick','freddy'];
arr.name = "ada";
 
for(var key in arr){
    console.log(key+': '+arr[key]);    
}
console.log('-----------分割线-----------');
for(var item of arr){    
    console.log(item);
}
// 0: nick
// 1: freddy
// name: ada
// -----------分割线-----------
// nick
// freddy

 

JavaScript 原有的for...in循环,只能获得对象的键名,不能直接获取键值。ES6 提供for...of循环,允许遍历获得键值。

var arr = ['a', 'b', 'c', 'd'];

for (let a in arr) {
  console.log(a); // 0 1 2 3
}

for (let a of arr) {
  console.log(a); // a b c d
}

上面代码表明,for...in循环读取键名,for...of循环读取键值。如果要通过for...of循环,获取数组的索引,可以借助数组实例的entries方法和keys方法(拓展,不常用)

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

 

for ... in是为遍历对象属性而构建的,不建议与数组一起使用

var obj = {a:1, b:2, c:3};
    
for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

 

 

数组中存放的是对象:

除了用(推荐用常规的)常规的for(var i=0;i<length;i++)遍历,还可以用for..in

var arr = [{
            age: 1,
            name: 'lily'
        },
        {
            age: 2,
            name: 'jake'
        },
        {
            age: 3,
            name: 'aa'
        }
    ]
    for (var i in arr) {
        if (!arr.hasOwnProperty(i)) {
            continue;
        }
        console.log(arr[i].name); //lily jake aa
    }

 最原始的写法就是for循环。

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}

这种写法比较麻烦,因此数组提供内置的forEach方法。

myArray.forEach(function (value) {
  console.log(value);
});

这种写法的问题在于,无法中途跳出forEach循环,break命令或return命令都不能奏效。

every 方法

every() 方法使用指定函数检测数组中的所有元素,它返回一个布尔值。:

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

注意: every() 不会对空数组进行检测。

注意: every() 不会改变原始数组。

[1,2,3,4,5].every(function(i){
  if (i === 3) {
    return false
  } else {
    console.log(i)
    return true  //如果不写,默认是return false 结果为: 1
  }
})
结果: 1, 2
[32, 33, 16, 40].every(item => {
    return item < 35
})
结果: false

 判断每一项都不能为空:

例子:

// 判断每一项促销设置不能为空
                    let typePriceVal = this.dataSource.every((item) => item.typePrice);
                    if (!typePriceVal) {
                        this.$message.error('促销设置不能为空');
                        return;
                    }

 注意:0返回的false,""空字符串返回的也是false,所以当判断每一项数字不为空的时候,可以用

!==''来判断而不是!=,举例:

let priceArr = formState.sku.list.every((item: { retail_price: string | number }) => item.retail_price !== '');
            if (!priceArr) {
                message.error('规格明细价格不能为空');
                return;
            }

或者用=== 0写法,而不是==

let priceArr = formState.sku.list.every(
                (item: { retail_price: string | number }) => item.retail_price || item.retail_price === 0
            );

 

 

some 方法

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

some() 方法会依次执行数组的每个元素:

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

注意: some() 不会对空数组进行检测。

注意: some() 不会改变原始数组。

var arr = [1,2,3,4,5]
var result = arr.some(function (item,index) {
    return item > 3
})
结果 true

 

filter 方法

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意: filter() 不会对空数组进行检测。

注意: filter() 不会改变原始数组。

const words = [1, 3, 4, 8, 5, 2];
const result = words.filter(word => {
  word = word + 3
  return word > 6
});
console.log(result);  // > Array [4, 8, 5]
console.log(words)   // > Array [1, 3, 4, 8, 5, 2]

map 方法

// ES5写法:
const array1 = [1, 4, 9, 16];
const map1 = array1.map(function(item) {
    return item * 2
})
// ES6写法:
const map1 = array1.map(item => item * 2);
// [2, 8, 18, 32]

根据上述代码可以看出 map()不会改变原数组,会返回一个新数组。下面举一个我经常在敲代码时用map()实现的 看起来改变了原数组的例子

const personList = [
    {name: 'aaa', age: 18},
    {name: 'bbb', age: 23},
    {name: 'ccc', age: 25}
]
// 看起来改变了原数组--修改(添加)对象数组中对象的某个属性
personList.map(item => {  //使用forEach()也可以实现  将map替换为forEach
    item.age += 1 // 修改
    item.gender = '男'  //添加
})
console.log(personList)
输出:
[
    {name: "aaa", age: 19, gender: "男"},
    {name: "bbb", age: 24, gender: "男"},
    {name: "ccc", age: 26, gender: "男"}
]

 最老的方法是最快的

 

 

资料:

MDN:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of 

阮一峰ES6:

https://es6.ruanyifeng.com/#docs/iterator

 

 
posted @ 2021-10-25 21:50  前端HL  阅读(145)  评论(0编辑  收藏  举报