前端开发必备!彻底搞懂 JavaScript 数组与对象的 8 大核心方法(附 React 实战)

118 阅读5分钟

在日常前端开发中,我们几乎每天都在和数组、对象打交道。无论是处理接口返回的数据、做状态管理,还是渲染列表组件,熟练掌握 JavaScript 提供的这些原生遍历与操作方法,是写出高效、可读性强代码的关键

今天,我将带你系统梳理 8 个最常用、最核心的数组与对象方法forEacheverysomefiltermapreducefind/findIndex、以及 ES6 的 Object.keys/values/entries,并结合 React 实战场景,让你真正“学以致用”。


1. forEach:基础遍历,但有局限

定义

forEach 用于按升序为数组中每个有效值执行一次回调函数。

array.forEach(function(currentValue, index, arr), thisValue)
  • currentValue(必需):当前元素的值
  • index(可选):当前元素索引
  • arr(可选):原数组

注意事项

  • 不能中途 breakcontinue,只能用 return 跳过本次回调。
  • 永远返回 undefined,即使你在回调中 return 其他值。
const nums = [1, 2, 3];
const result = nums.forEach(n => console.log(n));
console.log(result); // undefined

适用场景:仅用于执行副作用(如打印、修改外部变量),不适合做数据转换或提前终止的逻辑。


2. every:全真才为真

定义

检测数组所有元素是否都满足条件,一旦发现不满足的元素,立即返回 false,不再继续遍历。

[12, 54, 18, 130, 44].every(x => x >= 10); // true
[12, 5, 8, 130, 44].every(x => x >= 10);  // false

应用场景

  • 表单校验:所有输入项是否都合法?
  • 权限判断:用户是否拥有所有所需权限?
const permissions = ['read', 'write', 'delete'];
const userPerms = ['read', 'write', 'delete', 'admin'];

const hasAll = permissions.every(p => userPerms.includes(p));
console.log(hasAll); // true

短路优化:性能友好,一旦不满足立即退出。


3. some:一真即为真

定义

检测数组中是否有至少一个元素满足条件,一旦找到满足的元素,立即返回 true

[2, 5, 8, 1, 4].some(x => x > 10);  // false
[12, 5, 8, 1, 4].some(x => x > 10); // true

实战用途

  • 搜索功能:是否存在包含关键词的条目?
  • 状态判断:是否有未完成的任务?
const tasks = [
  { id: 1, done: false },
  { id: 2, done: true }
];

const hasPending = tasks.some(t => !t.done);
console.log(hasPending); // true

同样具备短路特性,效率高。


4. filter:筛选过滤,生成新数组

定义

返回一个新数组,包含所有通过测试函数的元素。不修改原数组

const strings = ["apple", "", "banana", " ", "cherry", null];
const validStrings = strings.filter(s => s && s.trim());
// ['apple', 'banana', 'cherry']

React 中的经典用法:瀑布流布局

<div className={styles.column}>
  {images
    .filter((_, i) => i % 2 === 0) // 筛选偶数索引图片
    .map(img => (
      <ImageCard key={img.id} img={img} />
    ))
  }
</div>

技巧:filter + map 组合拳,先筛选再渲染,逻辑清晰。


5. map:一对一映射,生成新数组

定义

对数组每个元素执行函数,返回新数组,长度与原数组一致。

const a = ['1', '2', '3'];
const result = a.map(value => value + '新元素');
// ['1新元素', '2新元素', '3新元素']

关键点

  • 返回新数组,不改变原数组。
  • 常用于 JSX 中渲染列表。
<ul>
  {users.map(user => (
    <li key={user.id}>{user.name}</li>
  ))}
</ul>

切记:React 中 mapkey 应使用稳定 ID,避免用 index,防止列表更新时出现渲染 bug。


6. reduce:累计器,功能最强大

定义

对数组元素“累积”计算,最终返回一个值。常用于求和、扁平化、分组等。

示例 1:求数组总和

const sum = [1, 2, 3, 4, 5].reduce((acc, curr) => acc + curr, 0);
// 15

示例 2:数组扁平化

const arrays = [[1,2], [3,4], [5,6]];
const flat = arrays.reduce((acc, curr) => acc.concat(curr), []);
// [1,2,3,4,5,6]

示例 3:对象分组(如按状态分类任务)

const tasks = [
  { id: 1, status: 'active' },
  { id: 2, status: 'done' },
  { id: 3, status: 'active' }
];

const grouped = tasks.reduce((acc, task) => {
  (acc[task.status] = acc[task.status] || []).push(task);
  return acc;
}, {});

// { active: [...], done: [...] }

💥 reduce 是函数式编程的灵魂,掌握它,你就掌握了数据变换的“上帝之手”。


7. find & findIndex:精准查找

find()

返回第一个满足条件的元素,否则返回 undefined

[1, 4, -5, 10].find(n => n < 0); // -5
[1, 4, 10, NaN].find(n => Object.is(NaN, n)); // NaN

findIndex()

返回第一个满足条件的元素索引,否则返回 -1

[1, 4, -5, 10].findIndex(n => n < 0); // 2
[1, 4, 0, 10].findIndex(n => n < 0); // -1

🆚 vs indexOf / includes

  • indexOf 只能查严格相等的值,不能查对象或复杂条件。
  • find 支持自定义判断逻辑,更灵活。
const users = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];
const user = users.find(u => u.id === 2); // { id: 2, name: 'B' }

8. Object.keys() / values() / entries():对象遍历三剑客

ES6 提供了三个静态方法,用于遍历对象的键、值、键值对。

方法返回用途
Object.keys(obj)字符串数组遍历属性名
Object.values(obj)值数组遍历属性值
Object.entries(obj)[key, value] 数组遍历键值对

✅ 实战 1:渲染配置项标题(keys

{Object.keys(settings).map(key => (
  <li key={key}><strong>{key}</strong></li>
))}

✅ 实战 2:显示用户信息(values

{Object.values(user).map((value, index) => (
  <li key={index}>{value}</li>
))}

✅ 实战 3:渲染键值对表格(entries

{Object.entries(userData).map(([key, value]) => (
  <tr key={key}>
    <td>{key}</td>
    <td>{value}</td>
  </tr>
))}

⚠️ 注意:

  1. key 推荐使用 key 本身(如对象 ID 或属性名),避免用 index
  2. 大对象可配合 useMemo 缓存结果,避免重复计算。
  3. TypeScript 中注意 Object.entries() 的类型推断。

📌 总结:一张表掌握核心差异

方法返回值是否改变原数组是否短路典型用途
forEachundefined执行副作用
everyboolean全部满足?
someboolean至少一个满足?
filter新数组筛选元素
map新数组数据映射
reduce累积值汇总、分组、扁平化
find元素 or undefined查找元素
findIndex索引 or -1查找索引
Object.keys字符串数组遍历键名
Object.values值数组遍历值
Object.entries键值对数组遍历键值对

写在最后

这 8 个方法是 JavaScript 数据处理的“瑞士军刀”。理解它们的差异和适用场景,能让你的代码更简洁、高效、函数式

  • 想遍历?用 forEach(副作用)或 map(映射)。
  • 想判断?用 every(全真)或 some(一真)。
  • 想筛选?用 filter
  • 想查找?用 find/findIndex
  • 想汇总?用 reduce
  • 想遍历对象?用 Object.keys/values/entries

🔥 记住:能用这些函数式方法的,就不要写 for 循环!

希望这篇文章能帮你彻底掌握这些核心方法。如果觉得有用,欢迎点赞、收藏、分享,也欢迎在评论区交流你的使用心得!