数组遍历
1. 普通for循环
let arr = [1,2,3,4,5]for (let i = 0; i < arr.length; i++) {console.log(arr[i])}// 输出结果// 1// 2// 3// 4// 5
2. 优化普通for循环
let arr = [1,2,3,4,5]for(var j = 0,len = arr.length; j < len; j++){console.log(arr[j]);}
3. forEach循环 (箭头函数改变this指向 手写forEach)
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
注意:forEach() 对于空数组是不会执行回调函数的。
let arr = [1,2,3,4,5]let obj = {a:1,b:2}arr.forEach((currentValue, index, arr) => {console.log(currentValue,index,arr,this)}, obj)arr.forEach(function(currentValue, index, arr){console.log(currentValue,index,arr,this)}, obj)
forEach() 的 continue 与 break
forEach() 本身是不支持的 continue 与 break 语句的,我们可以通过 some 和 every 来实现。
使用return语句实现continue关键字的效果:
4. map遍历
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意:map() 不会对空数组进行检测。
注意:map() 不会改变原始数组。
语法 array.map(function(currentValue,index,arr), thisValue)let arr = [1,2,3,4,5]let mapResult = arr.map((currentValue, index, arr)=>{console.log(currentValue,index,arr)return currentValue * index})console.log(mapResult)1 0 (5) [1, 2, 3, 4, 5]2 1 (5) [1, 2, 3, 4, 5]3 2 (5) [1, 2, 3, 4, 5]4 3 (5) [1, 2, 3, 4, 5]5 4 (5) [1, 2, 3, 4, 5](5) [0, 2, 6, 12, 20]
forEach 和 map 的区别
forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。
map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)来玩出更多的花样。
能用forEach()做到的,map()同样可以。反过来也是如此。
map()会分配内存空间存储新数组并返回,forEach()不会返回数据。
forEach()允许callback更改原始数组的元素。map()返回新的数组。
5. for... of
在可迭代对象(包括Array
,Map
,Set
,String
,TypedArray
,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
let arr = [1,2,3,4,5]for (let num of arr){console.log(num)}
对象遍历
1.for...in
(不适合数组)
for in 循环会遍历原型链上的属性
可以在for-in循环的时候添加 hasOwnProperty()方法来过滤掉非自有属性
// 创建一个对象并指定其原型,bar 为原型上的属性const obj = Object.create({bar: 'bar'})// foo 为对象自身的属性obj.foo = 'foo'for (let key in obj) {console.log(obj[key]) // foo, bar}for (let key in obj) {if (obj.hasOwnProperty(key)) {console.log(obj[key]) // foo}}
for...in
语句以任意顺序迭代对象的可枚举属性。
2.Object.keys()
Object.keys() 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性).
for in 循环和Object.keys()
方法都不会返回对象的不可枚举属性。
Object.values()
和Object.entries()
也都是返回一个给定对象自身可枚举属性的键值对数组。
Object.keys(obj).forEach((key) => {console.log(obj[key]) // foo})
3.Object.getOwnPropertyNames()
Object.getOwnPropertyNames()
也是 ES5 新增的一个对象方法,该方法返回对象自身属性名组成的数组,包括不可枚举的属性。
// 创建一个对象并指定其原型,bar 为原型上的属性// baz 为对象自身的属性并且不可枚举const obj = Object.create({bar: 'bar'}, {baz: {value: 'baz',enumerable: false}})obj.foo = 'foo'// 不包括不可枚举的 baz 属性Object.keys(obj).forEach((key) => {console.log(obj[key]) // foo})// 包括不可枚举的 baz 属性Object.getOwnPropertyNames(obj).forEach((key) => {console.log(obj[key]) // baz, foo})
4.Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols()
方法返回对象自身的 Symbol 属性组成的数组,不包括字符串属性
// 给对象添加一个不可枚举的 Symbol 属性Object.defineProperties(obj, {[Symbol('baz')]: {value: 'Symbol baz',enumerable: false}})// 给对象添加一个可枚举的 Symbol 属性obj[Symbol('foo')] = 'Symbol foo'Object.getOwnPropertySymbols(obj).forEach((key) => {console.log(obj[key]) // Symbol baz, Symbol foo})
5.Reflect.ownKeys()
Reflect.ownKeys()
方法是 ES 新增的静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和 Symbol 属性。
Reflect.ownKeys(obj).forEach((key) => {console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo})