JavaScript Array includes() 方法(深入浅出)

JavaScript Array includes() 方法:轻松判断数组中是否存在某元素

在日常开发中,我们经常需要判断一个数组里有没有某个特定的值。比如,用户是否已经选择了某个选项、某个权限是否已分配、或者某个状态是否已经存在。这时候,JavaScript Array includes() 方法就派上用场了。

它就像一个“搜索助手”,帮你快速判断某个元素是否存在于数组中,返回布尔值:true 表示存在,false 表示不存在。相比手动遍历数组,它更简洁、更易读,也更少出错。

如果你还在用 indexOf() 配合 === -1 来判断是否存在,那不妨试试 includes(),它更直观,也更安全。


语法结构与基本用法

includes() 方法的语法非常简单,几乎一看就懂:

array.includes(searchElement, fromIndex)
  • searchElement:要查找的元素,是必须的。
  • fromIndex:可选参数,表示从数组的哪个索引位置开始查找。默认是 0,也就是从头开始。

举个例子:

const fruits = ['apple', 'banana', 'orange'];

// 判断 'banana' 是否在数组中
console.log(fruits.includes('banana')); // true

// 判断 'grape' 是否在数组中
console.log(fruits.includes('grape'));  // false

小贴士includes() 是严格相等判断(===),所以类型不同也会返回 false。比如 1'1' 就不相等。


处理不同类型的数据

includes() 对不同类型的数据都能正确处理,但需要注意类型匹配。

数字与字符串的比较

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

// 数字 2 存在
console.log(numbers.includes(2)); // true

// 字符串 '2' 不存在(类型不同)
console.log(numbers.includes('2')); // false

❗ 注意:1'1' 是两个不同的值,includes() 不会做类型转换。这和 == 不同,它更严格。

对象与数组的判断

对于对象或数组这类引用类型,includes() 比较的是引用地址,而不是内容。

const obj1 = { name: 'Alice' };
const obj2 = { name: 'Alice' };
const arr = [obj1];

// obj1 在数组中吗?是的,引用一致
console.log(arr.includes(obj1)); // true

// obj2 在数组中吗?虽然内容一样,但引用不同
console.log(arr.includes(obj2)); // false

📌 比喻:就像两个完全一样的杯子,如果它们不是同一个杯子(引用不同),即使外观一样,也不能算“同一个”。


使用 fromIndex 参数控制搜索起点

fromIndex 参数让你可以灵活地控制搜索的起始位置。这在处理大型数组或需要部分搜索时特别有用。

const colors = ['red', 'green', 'blue', 'yellow', 'green'];

// 从索引 2 开始找 'green'
console.log(colors.includes('green', 2)); // true(在索引 2 后找到)

// 从索引 3 开始找 'green'
console.log(colors.includes('green', 3)); // true(在索引 4 找到)

// 从索引 4 开始找 'green'
console.log(colors.includes('green', 4)); // true(正好在索引 4)

// 从索引 5 开始找 'green'
console.log(colors.includes('green', 5)); // false(超出数组范围)

🔍 实际场景:假设你有一个用户权限数组,需要判断某个权限是否在“当前用户组”之后的列表中,fromIndex 就能帮你实现。


与 indexOf() 的对比:谁更优?

很多初学者会疑惑:includes()indexOf() 有什么区别?我们来对比一下:

特性 indexOf() includes()
返回值 元素索引,找不到返回 -1 布尔值:true/false
可读性 需要判断 >= 0 直接返回布尔值,更清晰
类型判断 严格相等(=== 严格相等(===
使用场景 需要知道位置时 只关心是否存在时
const items = ['a', 'b', 'c'];

// 使用 indexOf:需要判断是否不等于 -1
console.log(items.indexOf('b') !== -1); // true

// 使用 includes:直接判断是否存在
console.log(items.includes('b')); // true

✅ 推荐:当你只关心“是否存在”时,优先使用 includes(),代码更简洁,意图更明确。


实际应用案例:用户权限检查系统

假设你正在开发一个后台管理系统,需要判断当前用户是否有某个操作权限。

// 用户拥有的权限列表
const userPermissions = ['read', 'write', 'delete'];

// 要检查的权限
const requiredPermission = 'write';

// 检查用户是否有该权限
if (userPermissions.includes(requiredPermission)) {
  console.log('用户有权限执行此操作');
} else {
  console.log('权限不足,禁止访问');
}

💡 这种写法比 indexOf 更直观,也避免了因忘记判断 !== -1 而导致的逻辑错误。


边界情况与注意事项

1. 空数组

const emptyArray = [];
console.log(emptyArray.includes('any')); // false

空数组中任何元素都不存在,返回 false,这是合理的。

2. fromIndex 超出范围

如果 fromIndex 大于或等于数组长度,includes() 会直接返回 false

const data = [1, 2, 3];
console.log(data.includes(1, 5)); // false(索引 5 已超出)

3. fromIndex 为负数

负数索引从数组末尾开始计算:

const numbers = [10, 20, 30];

// 从倒数第 1 个元素开始找
console.log(numbers.includes(30, -1)); // true(倒数第 1 个是 30)

// 从倒数第 2 个元素开始找
console.log(numbers.includes(20, -2)); // true

⚠️ 注意:负数索引必须是有效的,否则行为不可预测。建议用 Math.max(0, fromIndex) 做安全处理。


性能考量:效率如何?

includes() 的时间复杂度是 O(n),即最坏情况下需要遍历整个数组。这和 indexOf() 一样,都是线性查找。

不过,includes() 的优势在于:

  • 代码更简洁
  • 不易出错(避免 indexOf=== -1 漏写)
  • 更符合“语义化”编程思想

对于小到中等规模的数组(几千个元素以内),性能差异几乎可以忽略。所以,优先考虑可读性,而不是微小的性能差异


总结:为什么你应该用 includes()

JavaScript Array includes() 方法是一个简单但强大的工具。它让数组元素的存在性判断变得清晰、安全、易读。

  • 当你只需要判断“有没有”,而不是“在哪”,就用 includes()
  • 它支持 fromIndex,灵活控制搜索范围。
  • 类型严格,避免隐式转换带来的陷阱。
  • 语法简洁,可读性强,是现代 JavaScript 的推荐写法。

无论你是初学者还是中级开发者,掌握这个方法都能让你的代码更优雅、更健壮。

最后提醒一句:别再用 indexOf() 配合 !== -1 了,includes() 才是正解。它不仅更短,也更不容易出错。

现在,你已经掌握了 JavaScript Array includes() 方法的全部核心知识点。赶紧在你的项目中用起来吧!