数组的迭代数组里面每个对象添加属性值_JS数组和对象循环遍历的几种实现方式...

本文详细介绍了JavaScript中常见的数组遍历方法,包括普通for循环、优化for循环、forEach、map以及for...of。同时,文章还探讨了这些方法在处理数组时的特点、区别以及适用场景,如forEach适合仅处理数据,map则用于改变数据并返回新数组。此外,还讲解了如何通过其他方式模拟forEach和map中的continue和break。最后,对比了for...in、Object.keys()、Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和Reflect.ownKeys()在遍历对象属性时的差异和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

905d18b267cdc2e681958372f9b03ce4.png

数组遍历

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

在可迭代对象(包括 ArrayMapSetStringTypedArray,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()方法是 ES2015 新增的静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和 Symbol 属性。

Reflect.ownKeys(obj).forEach((key) => {
 console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})

五种方法对比

6ba3c23ef948a3ecd6e51b845bb6e01c.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值