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