js中的各种对象遍历方法

1.forEach方法

forEach是javaScrip中数组(Array)的一个内置方法,用于遍历数组中的每个元素并执行回调函数。

array.forEach(function(currentValue, index, array) {
  // 执行的操作
}, thisArg);

参数说明:

  • currentValue:当前处理的数组元素(必需)

  • index:当前元素的索引(可选)

  • array:正在操作的数组本身(可选)

  • thisArg:执行回调时用作 this 的值(可选)

  • 基本用法示例

  • const fruits = ['apple', 'banana', 'orange'];
    
    // 简单遍历
    fruits.forEach(function(fruit) {
      console.log(fruit);
    });
    // 输出: apple, banana, orange
    
    // 带索引的遍历
    fruits.forEach(function(fruit, index) {
      console.log(index + ': ' + fruit);
    });
    // 输出: 0: apple, 1: banana, 2: orange
    箭头函数写法
  • fruits.forEach((fruit,index)) =>{
    console.log(${index+1}: ${fruit});
    }

    特点与注意事项

  • 不会改变原数组(除非在回调中手动修改)
    const numbers = [1, 2, 3];
    numbers.forEach(num => num * 2); // 原数组不变
    console.log(numbers); // [1, 2, 3]
    没有返回值(返回 undefined
    const result = [1, 2, 3].forEach(num => num * 2);
    console.log(result); // undefined
    无法中途跳出循环(不能使用 break 或 return
    // 这样不会停止循环
    [1, 2, 3].forEach(num => {
      if (num === 2) return; // 只是跳过当前迭代
      console.log(num);
    });
    会跳过空位
    [1, , 3].forEach(num => console.log(num)); // 输出: 1, 3

  • 适用场景

  • 需要对数组每个元素执行相同操作

  • 不需要中途退出循环

  • 代码可读性优先于性能

  • 不适用场景

  • 需要根据条件提前终止循环(改用 for 或 some/every

  • 需要返回新数组(改用 map

  • 需要过滤数组(改用 filter)

  • 2.map--数组映射转换

  • map是JavaScript 数组的高阶函数,用于处理数组并返回新数组。而我们的forEach不会返回新数组。map()方法会创建一个新数组,其结果是原数组的每个元素调用一次提供的函数返回值。

  • const newArray = arr.map(function(currentValue, index, array) {
      // 返回处理后的元素
    }, thisArg);

    特点

  • 返回新数组(不修改原数组)

  • 新数组长度与原数组相同

  • 用于数据转换/格式化

  • const numbers = [1, 2, 3];
    
    // 所有元素乘以2
    const doubled = numbers.map(num => num * 2);
    console.log(doubled); // [2, 4, 6]
    
    // 转换为对象数组
    const objects = numbers.map(num => ({ value: num }));
    console.log(objects); // [{value: 1}, {value: 2}, {value: 3}]

  • 实际应用场景

  • API数据格式化

  • 渲染列表前的数据准备

  • 数值计算转换

3.filter---数组过滤

基本概念:filter()方法会创建一个新数组,包含通过所提供的函数测试的所有元素。

const newArray = arr.filter(function(currentValue, index, array) {
  // 返回true保留元素,false过滤元素
}, thisArg);

何时选择

  • 特点

  • 返回新数组(不修改原数组)

  • 新数组长度 ≤ 原数组长度

  • 用于数据筛选

  • const numbers = [1, 2, 3, 4, 5];
    
    // 过滤偶数
    const evens = numbers.filter(num => num % 2 === 0);
    console.log(evens); // [2, 4]
    
    // 过滤长度大于3的字符串
    const words = ['apple', 'banana', 'pear'];
    const longWords = words.filter(word => word.length > 4);
    console.log(longWords); // ['banana']

    实际应用场景

  • 搜索/筛选功能

  • 数据清理(去除无效数据)

  • 权限过滤

  • 注意事项

  • 不修改原数组:两者都返回新数组,不影响原数组

  • 性能考虑:大数据量时,链式调用多个方法可能影响性能

  • 需要转换数据格式 → 用 map

  • 需要筛选数据子集 → 用 filter

  • 需要先筛选再转换 → 链式调用 filter().map()

  • 空位处理map会保留空位,filter会跳过空位

  • 异步问题:回调函数中使用异步代码需要特别处理

  • 4.for...of循环

  • 基本概念:for...of 是 ES6 引入的循环语法,用于遍历可迭代对象(如 Array、String、Map、Set 等)

  • for (const element of iterable) {
      // 执行操作
    }

    特点

  • 可遍历任何可迭代对象(实现了 [Symbol.iterator] 方法的对象)

  • 可以直接获取元素值(不需要通过索引)

  • 可以使用 break 和 continue 控制循环

  • 不提供索引(需要索引时可结合 entries()

  • const fruits = ['apple', 'banana', 'orange'];
    
    // 基本用法
    for (const fruit of fruits) {
      console.log(fruit);
    }
    
    // 带索引的遍历
    for (const [index, fruit] of fruits.entries()) {
      console.log(index, fruit);
    }
    
    // 可提前终止
    for (const fruit of fruits) {
      if (fruit === 'banana') break;
      console.log(fruit); // 只输出 'apple'
    }

    与 forEach 的区别

  • for...of 可以使用 break/continue

  • for...of 可以遍历任何可迭代对象,而 forEach 只是数组方法

  • for...of 性能通常比 forEach 更好

5.some方法

基本概念:some()测试数组中是否至少有一个元素通过了提供的函数测试。

array.some(function(currentValue, index, array) {
  // 返回布尔值
}, thisArg);

特点

  • 返回布尔值(true/false)

  • 遇到第一个返回 true 的元素就停止遍历

  • 空数组调用始终返回 false

  • 不修改原数组

const numbers = [1, 2, 3, 4, 5];

// 检查是否有偶数
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true

// 检查是否有大于10的数
const hasLargeNumber = numbers.some(num => num > 10);
console.log(hasLargeNumber); // false

实际应用

  • 权限检查(是否有某项权限)

  • 表单验证(是否有无效字段)

  • 搜索(是否存在匹配项)

6.every方法

基本概念:every()测试数组中的所有元素是否都通过了提供的函数测试。

array.every(function(currentValue, index, array) {
  // 返回布尔值
}, thisArg);

特点

  • 返回布尔值(true/false)

  • 遇到第一个返回 false 的元素就停止遍历

  • 空数组调用始终返回 true(空真规则)

  • 不修改原数组

const numbers = [2, 4, 6, 8, 10];

// 检查是否都是偶数
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // true

// 检查是否都小于5
const allSmall = numbers.every(num => num < 5);
console.log(allSmall); // false (6不小于5)

实际应用

  • 表单验证(所有字段是否有效)

  • 权限检查(是否具备所有权限)

  • 数据完整性检查

JavaScript 数组遍历方法对比表

方法返回值是否修改原数组能否中断循环空数组处理主要用途性能特点
forEachundefined跳过空位遍历执行操作中等,最通用
map新数组保留空位数据转换/映射稍慢,需处理所有元素
filter新数组跳过空位数据筛选中等,可能提前结束
for...of可手动修改可(break)不执行通用遍历较快
some布尔值可(短路)返回false检查是否存在符合条件的元素最快(可能提前结束)
every布尔值可(短路)返回true检查所有元素是否都符合条件最快(可能提前结束)

详细对比说明

1. 返回值差异

  • 无返回值forEachfor...of

  • 返回新数组mapfilter

  • 返回布尔值someevery

2. 循环控制能力

  • 可完全中断for...of (使用break), some/every (短路特性)

  • 不可中断forEachmapfilter

3. 空数组处理

  • 特殊返回

    • some([]) → false

    • every([]) → true (空真规则)

  • 跳过不执行forEachfor...of

  • 返回空数组map([])filter([])

4. 性能考量

  • 最快some/every (可能提前结束)

  • 较快for...of (原生循环)

  • 中等forEachfilter

  • 稍慢map (必须处理所有元素)

5. 典型使用场景

  • 数据转换 → map

  • 数据筛选 → filter

  • 简单遍历 → forEach 或 for...of

  • 存在性检查 → some

  • 全体性检查 → every

  • 需要流程控制 → for...of

选择建议

  1. 需要 转换数组结构 → map

  2. 需要 过滤数据 → filter

  3. 需要 检查是否至少一个元素满足条件 → some

  4. 需要 检查所有元素是否满足条件 → every

  5. 需要 灵活控制循环过程 → for...of

  6. 只需要 简单遍历执行操作 → forEach

JavaScript 中,遍历对象属性的方法有多种,每种方法适用于不同的场景,具体取决于是否需要遍历可枚举属性、不可枚举属性、Symbol 属性,或者是否需要排除原型链上的属性。 ### 使用 `for...in` 循环 `for...in` 循环可以遍历对象自身的可枚举属性以及继承自原型链的可枚举属性。因此,在使用时通常需要结合 `hasOwnProperty()` 方法来确保只处理对象自身的属性。 ```javascript const obj = { a: 1, b: 2 }; for (let key in obj) { if (obj.hasOwnProperty(key)) { console.log(key + ": " + obj[key]); } } ``` ### 使用 `Object.keys()` `Object.keys()` 返回一个数组,包含对象自身的所有可枚举属性名称。该方法不会遍历不可枚举属性或原型链中的属性。 ```javascript const obj = { a: 1, b: 2 }; Object.keys(obj).forEach(key => { console.log(key + ": " + obj[key]); }); ``` ### 使用 `Object.getOwnPropertyNames()` `Object.getOwnPropertyNames()` 返回一个数组,包含对象自身的所有属性名(包括不可枚举属性),但不包括 Symbol 属性。 ```javascript const obj = { a: 1 }; Object.defineProperty(obj, 'b', { value: 2, enumerable: false }); Object.getOwnPropertyNames(obj).forEach(key => { console.log(key + ": " + obj[key]); }); ``` ### 使用 `Reflect.ownKeys()` `Reflect.ownKeys()` 返回一个数组,包含对象自身的所有属性名,包括不可枚举属性和 Symbol 属性,是目前最全面的对象属性遍历方法。 ```javascript const sym = Symbol('id'); const obj = { [sym]: 123, a: 1 }; Object.defineProperty(obj, 'b', { value: 2, enumerable: false }); Reflect.ownKeys(obj).forEach(key => { console.log(key + ": " + obj[key]); }); ``` ### 使用 `Object.entries()` `Object.entries()` 返回一个数组,包含对象自身的可枚举属性的键值对。该方法非常适合需要同时获取键和值的情况。 ```javascript const obj = { a: 1, b: 2 }; Object.entries(obj).forEach(([key, value]) => { console.log(key + ": " + value); }); ``` ### 使用 `Object.values()` `Object.values()` 返回一个数组,包含对象自身的所有可枚举属性值。 ```javascript const obj = { a: 1, b: 2 }; Object.values(obj).forEach(value => { console.log(value); }); ``` ### 总结 - 如果需要遍历对象自身所有属性(包括不可枚举和 Symbol 属性),应使用 `Reflect.ownKeys()`。 - 如果仅需遍历可枚举属性,可以使用 `Object.keys()` 或 `for...in`(配合 `hasOwnProperty()`)。 - 如果需要获取键值对形式的数据,推荐使用 `Object.entries()`。 - 如果需要获取属性值的数组,可以使用 `Object.values()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值