玩转 JavaScript 遍历方法


遍历是指按照一定的顺序访问数据结构中的每一个元素。无论是处理数组、对象还是更复杂的数据结构,遍历都是一个基础且关键的操作。本文将介绍几种常用的遍历方法,并通过实例演示它们的使用方法。

一、常规遍历方法

1.1 for循环

  • for 循环是一种基础且强大的循环结构,适用于任何类型的数组遍历需求。

参数说明

  • 初始化表达式:定义一个计数变量。
  • 条件表达式:每次循环前检查该表达式是否为真。
  • 更新表达式:每次循环后执行,通常用来递增或递减计数器。

注意事项

  • 确保更新表达式能够正确改变计数器以避免无限循环。
  • 使用时要注意数组长度的变化可能影响循环次数。

代码示例

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

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

1.2 while循环

  • while 循环会先检查一个指定的条件,如果该条件为真(即返回 true),则执行循环体中的代码块。这个过程会一直重复,直到条件不再为真。

参数说明

  • condition:每次循环开始前都会被评估的布尔表达式。如果 condition 为 true,则执行循环体;否则退出循环。

代码示例

let i = 1;

while (i <= 5) {
  console.log(i);
  i++;
}

注意事项

  • 确保在循环体内有适当的语句来改变 condition 的值,以避免无限循环。
  • 如果 condition 在第一次评估时就为 false,那么循环体内的代码将不会被执行。

1.3 do…while 循环

  • do…while 循环与 while 循环类似,但有一个关键的区别:do…while 循环至少会执行一次循环体,然后才去检查条件。即使条件一开始就不满足,循环体也会执行一次。

参数说明

  • statement:要执行的代码块。
  • condition:在每次循环结束时都会被评估的布尔表达式。如果 condition 为 true,则继续下一次循环;否则退出循环。

代码示例

let i = 1;

do {
  console.log(i);
  i++;
} while (i <= 5);

注意事项

  • 由于 do…while 循环至少会执行一次循环体,因此它适用于那些需要确保至少执行一次操作的情况。
  • 在循环体内必须有适当的逻辑来更新 condition,以避免无限循环。

二、数组遍历方法

2.1 forEach()

  • forEach 方法对数组的每个元素执行一次提供的函数。

参数说明

  • callback - 在数组每个元素上执行的函数,接受三个参数:
    • currentValue - 当前正在处理的元素。
    • index - 正在处理的当前元素的索引。
    • array - 调用forEach的数组。
  • thisArg - 执行回调时用作this的值(可选)。

代码示例

let arr = [1, 2, 3, 4, 5];

arr.forEach((item, index) => {
  console.log(item, index);
});

注意事项

  • forEach不会改变原数组。
  • 不支持中断迭代(如break),如果需要中断,考虑使用其他方法或传统的for循环。

2.2 map()

  • map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

参数说明

  • callback - 在数组每个元素上执行的函数,接受三个参数:
    • currentValue - 当前正在处理的元素。
    • index - 正在处理的当前元素的索引。
    • array - 调用forEach的数组。
  • thisArg - 执行回调时用作this的值(可选)。

代码示例

let arr = [1, 2, 3, 4, 5];

arr.map((item, index) => {
  console.log(item, index);
});

const newArr = arr.map((item) => item * 2);
console.log(newArr); // [2, 4, 6, 8, 10]

注意事项

  • map总是返回一个新数组。
  • 如果不希望创建新数组,请考虑使用forEach或其他方法。

2.3 for…of

  • for…of 是一种迭代语句,用于遍历可迭代对象(如数组)的值。

参数说明

  • 无:直接使用数组或任何实现了@@iterator方法的对象。

代码示例

let arr = [1, 2, 3, 4, 5];

for (const item of arr) {
  console.log(item);
}

注意事项

  • for…of 只能访问数组元素的值,不能直接获取索引。
  • 对于稀疏数组,for…of 不会遍历空槽位。

2.4 filter()

  • filter() 方法创建一个新数组,其中包含所有通过测试函数的元素。

参数说明

  • callback - 在数组每个元素上执行的函数,接受三个参数:
    • currentValue - 当前正在处理的元素。
    • index - 正在处理的当前元素的索引。
    • array - 调用forEach的数组。
  • thisArg - 执行回调时用作this的值(可选)。

代码示例

let arr = [1, 2, 3, 4, 5];

const newArr = arr.filter((item) => item > 2);

console.log(newArr);

注意事项

  • filter() 不会改变原数组(返回一个新数组)。
  • 如果没有元素通过测试,则返回空数组。

2.5 some()、every()

  • 这两个方法分别用于检测数组中是否有至少一个/全部元素满足条件。

参数说明

  • callback - 在数组每个元素上执行的函数,接受三个参数:
    • currentValue - 当前正在处理的元素。
    • index - 正在处理的当前元素的索引。
    • array - 调用forEach的数组。
  • thisArg - 执行回调时用作this的值(可选)。

代码示例

let arr = [1, 2, 3, 4, 5];

const newArr1 = arr.some((item) => item > 2);
const newArr2 = arr.every((item) => item > 2);

console.log(newArr1); // true
console.log(newArr2); // false

注意事项

  • some() 只要找到一个符合条件的元素就会停止遍历。
  • every() 只要发现一个不符合条件的元素就会停止遍历。

2.6 reduce()

  • reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

参数说明

  • callback:执行数组中每个值的函数,接受四个参数:累加器、当前值、当前索引、原数组。
  • initialValue:作为第一次调用callback函数时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素。

代码示例

let arr = [1, 2, 3, 4, 5];

const sum = arr.reduce((acc, cur) => acc + cur);

console.log(sum);

注意事项

  • 如果未提供初始值且数组为空,则会抛出错误。
  • 初始值可以影响最终结果。

2.7 find() 和 findIndex()

  • find() 返回数组中满足提供的测试函数的第一个元素的值;而findIndex()则返回该元素的索引。

参数说明

  • callback - 在数组每个元素上执行的函数,接受三个参数:
    • currentValue - 当前正在处理的元素。
    • index - 正在处理的当前元素的索引。
    • array - 调用find的数组。
  • thisArg - 执行回调时用作this的值(可选)。

代码示例

let arr = [1, 2, 3, 4, 5];

const num = arr.find((item) => item > 3);
const index = arr.findIndex((item) => item > 3);

console.log(num);
console.log(index);

注意事项

  • 如果没有找到匹配项,find() 返回undefined,findIndex() 返回-1。

2.8 keys(), values(), entries()

  • 这些方法都返回一个新的迭代器对象,可用于遍历数组。

  • keys() 返回键名的迭代器。

  • values() 返回键值的迭代器。

  • entries() 返回键值对的迭代器。

代码示例

let arr = [1, 2, 3, 4, 5];

for (const key of arr.keys()) {
  // 0, 1, 2, 3, 4
  console.log(key);
}

for (const values of arr.values()) {
  // 1, 2, 3, 4, 5
  console.log(values);
}

for (const [key, value] of arr.entries()) {
  // Key: 0, Value: 1
  // Key: 1, Value: 2
  // Key: 2, Value: 3
  // Key: 3, Value: 4
  // Key: 4, Value: 5
  console.log(`Key: ${key}, Value: ${value}`);
}

注意事项

  • 这些方法不会修改原始数组。
  • 它们非常适合与for…of循环结合使用。

三、对象遍历方法

3.1 for…in 循环

  • 遍历一个对象的所有可枚举属性,包括原型链上的属性。
  • 参数: 不需要额外参数,直接作用于对象。

代码示例

const obj = { a: 1, b: 2, c: 3 };

for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}
  • 注意事项: 使用时需注意检查是否为对象自身的属性,以避免意外地遍历到继承自原型链的属性。

3.2 Object.keys() Object.values() Object.entries()

  • 返回一个包含对象自身所有可枚举属性名称的数组。

Object.keys()

  • 返回一个数组
  • 数组成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键名

Object.values()

  • 返回一个数组
  • 数组成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键值

Object.entries()

  • 返回一个数组
  • 数组成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键值对数组

代码示例

const obj = { a: 1, b: 2, c: 3 };

const keys = Object.keys(obj);
console.log(keys); // 输出 ["a", "b", "c"]

const values = Object.values(obj);
console.log(values); // 输出 [1, 2, 3]

const entries = Object.entries(obj);
console.log(entries); // 输出 [["a", 1], ["b", 2], ["c", 3]]
  • 注意事项: 只返回可枚举的自有属性。

3.3 Object.getOwnPropertyNames()

  • 返回一个包含指定对象所有自身属性(不包括继承的属性)名称的数组。

代码示例

const obj = { a: 1, b: 2, c: 3 };

const propertyNames = Object.getOwnPropertyNames(obj);
console.log(propertyNames); // 输出 ["a", "b", "c"]
  • 包括不可枚举的属性名。

3.4 Object.getOwnPropertySymbols()

  • 返回一个包含指定对象自身所有符号类型属性键的数组。

代码示例

const obj = {};
const symA = Symbol('a');
const symB = Symbol('b');
obj[symA] = 'symbol A';
obj[symB] = 'symbol B';

const symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols); // 输出 [Symbol(a), Symbol(b)]
  • 主要用于处理ES6引入的Symbol类型数据,这类数据通常作为私有属性使用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会思想的苇草i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值