今天是2026年2月17日农历正月初一,在2026 愿大家:身体健康无病痛,收入翻番钱包鼓! 代码 0 Error 0 Warning,需求一次过,上线零回滚!策马扬鞭,从小白进阶专家,新年一路 “狂飙”!🧧🐎 给大家拜年啦~
前言
前端里权限判断、表单校验、勾选状态,几乎都要判断「数组里有没有某个值」或「是否全部满足条件」。很多人习惯用 for 循环 + if 一把梭,或者 indexOf 判断,写多了既啰嗦又容易漏边界情况。
用 find / some / every / includes 这四个方法,可以把「查找 → 判断 → 校验」写得更短、更语义化,也更好处理边界情况。本文用 10 个常见场景,把日常该怎么选、为什么这么选、容易踩的坑讲清楚。
适合读者:
- 会写 JS,但对
find/some/every/includes用哪个、什么时候用有点模糊 - 刚学 JS,希望一开始就养成清晰的数组判断写法
- 有经验的前端,想统一团队里的权限/校验/状态判断写法
一、先搞清楚:find / some / every / includes 在干什么
这四个方法都不是黑魔法,本质是:在不动原数组的前提下,用一次遍历完成「查找 / 判断是否存在 / 判断是否全部满足」。
| 方法 | 在干什么 | 返回值 | 什么时候停 |
|---|---|---|---|
find | 找第一个符合条件的元素 | 找到的元素,找不到返回 undefined | 找到第一个就停 |
some | 判断是否至少有一个满足条件 | true 或 false | 找到第一个就停(短路) |
every | 判断是否全部满足条件 | true 或 false | 遇到第一个不满足就停(短路) |
includes | 判断数组里是否包含某个值(严格相等) | true 或 false | 遍历完或找到就停 |
// 传统 for:意图分散,还要自己管 break
let found = null;
for (let i = 0; i < users.length; i++) {
if (users[i].id === targetId) {
found = users[i];
break;
}
}
// find:一眼看出「找第一个 id 匹配的」
const found = users.find((u) => u.id === targetId);
记住一点:能用语义化方法就不用循环,用 find/some/every/includes 把「要查什么、要判断什么」写清楚,比「怎么循环、怎么 break」更重要。
二、数组查找与判断的 10 个常用场景
假设接口返回的数据类似:
const users = [
{ id: 1, name: '张三', role: 'admin', status: 'active' },
{ id: 2, name: '李四', role: 'user', status: 'active' },
{ id: 3, name: '王五', role: 'user', status: 'inactive' },
];
const permissions = ['read', 'write', 'delete'];
const selectedIds = [1, 2];
下面 10 个写法,覆盖权限判断、表单校验、勾选状态等真实场景。
场景 1:找第一个符合条件的对象(find)
const admin = users.find((user) => user.role === 'admin');
// { id: 1, name: '张三', role: 'admin', status: 'active' }
// 找不到返回 undefined
const superAdmin = users.find((user) => user.role === 'superAdmin');
// undefined
适用: 默认选中第一项、取第一个有效配置、根据 id 找对象等。
注意: find 找不到返回 undefined,后续解构或访问属性要处理,用 ?? 给默认值。
场景 2:判断是否至少有一个满足条件(some)
const hasAdmin = users.some((user) => user.role === 'admin');
// true
const hasInactive = users.some((user) => user.status === 'inactive');
// true
适用: 权限判断「是否有任一管理员」、表单校验「是否有错误项」、状态判断「是否有未完成项」等。
注意: 空数组时 some 返回 false,业务上要结合「空列表算通过还是不算」处理。
场景 3:判断是否全部满足条件(every)
const allActive = users.every((user) => user.status === 'active');
// false(因为有王五是 inactive)
const allHaveId = users.every((user) => user.id != null);
// true
适用: 表单校验「是否全部勾选」、权限判断「是否全部有权限」、状态判断「是否全部完成」等。
注意: 空数组时 every 返回 true(空真),业务上要结合「空列表算通过还是不算」处理。
场景 4:判断数组是否包含某个值(includes)
const hasRead = permissions.includes('read');
// true
const hasExecute = permissions.includes('execute');
// false
适用: 简单值数组的包含判断、权限列表判断、标签列表判断等。
注意: includes 底层用 严格相等=== 做比较,这对「简单值(string / number / boolean)」很友好,但对「对象 / 数组」这类引用类型完全不适用,因为===比较的是内存地址而非内容。
场景 5:权限判断:是否有某个权限(some + includes)
const userPermissions = ['read', 'write'];
const requiredPermission = 'delete';
const hasPermission = userPermissions.includes(requiredPermission);
// false
// 或判断多个权限中是否有任一
const requiredPermissions = ['delete', 'admin'];
const hasAnyPermission = requiredPermissions.some((perm) =>
userPermissions.includes(perm)
);
// false
适用: 按钮权限控制、路由权限控制、功能权限判断等。
推荐: 简单值用 includes,复杂条件用 some + 回调。
场景 6:表单校验:是否全部必填项已填(every)
const formFields = [
{ name: 'username', value: '张三', required: true },
{ name: 'email', value: '', required: true },
{ name: 'phone', value: '13800138000', required: false },
];
const allRequiredFilled = formFields
.filter((field) => field.required)
.every((field) => field.value.trim() !== '');
// false(email 为空)
适用: 表单提交前校验、批量操作前校验、多步骤流程校验等。
推荐: 先 filter 筛出必填项,再用 every 判断是否全部有值。
场景 7:勾选状态:是否全部选中(every)
const checkboxes = [
{ id: 1, checked: true },
{ id: 2, checked: true },
{ id: 3, checked: false },
];
const allChecked = checkboxes.every((item) => item.checked);
// false
const hasChecked = checkboxes.some((item) => item.checked);
// true
适用: 全选/反选功能、批量操作按钮状态、表格多选状态等。
推荐: every 判断全选,some 判断是否有选中项。
场景 8:找第一个并给默认值(find+ ??)
const defaultUser = users.find((user) => user.role === 'admin') ?? {
id: 0,
name: '默认用户',
role: 'guest',
};
适用: 默认选中第一项、取第一个有效配置、兜底默认值等。
注意: find 找不到返回 undefined,用 ?? 可以统一成默认对象,避免后面解构报错。
场景 9:对象数组是否包含某个 id(some)
const targetId = 2;
const exists = users.some((user) => user.id === targetId);
// true
// 或判断多个 id 中是否有任一存在
const targetIds = [2, 5];
const hasAny = targetIds.some((id) => users.some((user) => user.id === id));
// true(2 存在)
适用: 判断选中项是否在列表里、判断 id 是否已存在、去重前判断等。
注意: 对象数组不能用 includes,要用 some + 条件判断。
场景 10:组合判断:全部满足 A 且至少一个满足 B(every +some)
const allActive = users.every((user) => user.status === 'active');
const hasAdmin = users.some((user) => user.role === 'admin');
// 业务逻辑:全部激活 且 有管理员
const canOperate = allActive && hasAdmin;
// false(因为有 inactive 的)
适用: 复杂业务规则判断、多条件组合校验、权限组合判断等。
推荐: 把每个条件拆成变量,用名字表达「这一步在判断什么」,可读性和调试都会好很多。
三、容易踩的坑
1. find 找不到返回 undefined,直接解构会报错
const user = users.find((u) => u.id === 999);
const { name } = user; // TypeError: Cannot read property 'name' of undefined
正确: 用 ?? 给默认值,或先判断再解构。
const user = users.find((u) => u.id === 999) ?? { name: '未知' };
// 或
const user = users.find((u) => u.id === 999);
if (user) {
const { name } = user;
}
2. 空数组时 every 返回 true,some 返回 false
[].every((x) => x > 0); // true(空真)
[].some((x) => x > 0); // false
业务上要结合「空列表算通过还是不算」处理。例如表单校验,空列表可能应该算「未填写」而不是「通过」。
const fields = [];
const allFilled = fields.length > 0 && fields.every((f) => f.value);
// 先判断长度,再 every
3. includes 只能判断简单值,对象数组要用 some
const users = [{ id: 1 }, { id: 2 }];
users.includes({ id: 1 }); // false(对象引用不同)
// 正确:用 some + 条件判断
users.some((user) => user.id === 1); // true
4. find 和 filter 的区别:find 只找第一个,filter 找全部
const firstAdmin = users.find((u) => u.role === 'admin');
// 返回第一个对象或 undefined
const allAdmins = users.filter((u) => u.role === 'admin');
// 返回数组,可能为空数组 []
要「第一个」用 find,要「全部」用 filter,别混用。
5. some 和 every 的短路特性:找到就停
const users = [
{ id: 1, role: 'admin' },
{ id: 2, role: 'user' },
{ id: 3, role: 'admin' },
];
// some:找到第一个 admin 就停,不会继续遍历
users.some((u) => {
console.log(u.id); // 只打印 1
return u.role === 'admin';
});
// every:遇到第一个不是 admin 就停
users.every((u) => {
console.log(u.id); // 打印 1, 2(遇到 user 就停)
return u.role === 'admin';
});
性能上这是好事,但如果有副作用(如打印、修改外部变量),要注意只执行到第一个匹配项。
四、实战推荐写法模板
权限判断(是否有某个权限):
const userPermissions = response?.data?.permissions ?? [];
const canDelete = userPermissions.includes('delete');
// 或判断多个权限中是否有任一
const canManage = ['delete', 'admin'].some((perm) =>
userPermissions.includes(perm)
);
表单校验(是否全部必填项已填):
const fields = formData?.fields ?? [];
const isValid = fields
.filter((field) => field.required)
.every((field) => field.value?.trim() !== '');
// 或更严格的校验
const isValid = fields.length > 0 &&
fields.filter((f) => f.required).every((f) => f.value?.trim() !== '');
勾选状态(全选/部分选中):
const items = tableData ?? [];
const allChecked = items.length > 0 && items.every((item) => item.checked);
const hasChecked = items.some((item) => item.checked);
// 全选按钮状态
const selectAllDisabled = items.length === 0;
const selectAllChecked = allChecked;
找第一个并给默认值:
const defaultItem = (response?.data?.list ?? []).find(
(item) => item.isDefault
) ?? {
id: 0,
name: '默认选项',
value: '',
};
对象数组是否包含某个 id:
const selectedIds = [1, 2, 3];
const targetId = 2;
const isSelected = selectedIds.includes(targetId);
// 对象数组
const users = response?.data?.users ?? [];
const targetId = 2;
const exists = users.some((user) => user.id === targetId);
五、小结
| 场景 | 推荐写法 | 返回值 |
|---|---|---|
| 找第一个符合条件的对象 | list.find(item => ...) | 对象或 undefined |
| 判断是否至少有一个满足 | list.some(item => ...) | true 或 false |
| 判断是否全部满足 | list.every(item => ...) | true 或 false |
| 判断是否包含某个值(简单值) | list.includes(value) | true 或 false |
| 找第一个并给默认值 | list.find(...) ?? 默认值 | 对象或默认值 |
| 对象数组是否包含某个 id | list.some(item => item.id === id) | true 或 false |
| 表单校验:全部必填已填 | list.filter(...).every(...) | true 或 false |
| 勾选状态:全部选中 | list.every(item => item.checked) | true 或 false |
记住:find 负责「找」,some 负责「至少一个」,every 负责「全部」,includes 负责「简单值包含」。日常写权限、校验、状态判断时,先想清楚是要找对象、判断存在、判断全部,还是简单值包含,再选方法,代码会干净很多,也少踩坑。
特别提醒:
find找不到返回undefined,记得用??给默认值- 空数组时
every为true,some为false,业务上要结合长度判断 - 对象数组不能用
includes,要用some+ 条件判断
文章到这里结束。如果你日常写权限判断、表单校验、勾选状态时经常纠结用哪个方法,希望这篇能帮你定个型。
以上就是本次的学习分享,欢迎大家在评论区讨论指正,与大家共勉。
我是 Eugene,你的电子学友。
如果文章对你有帮助,别忘了点赞、收藏、加关注,你的认可是我持续输出的最大动力~