Array.prototype.includes 的精准匹配

在 ECMAScript 2016 (ES7) 中,JavaScript 数组获得了一个简单但极其有用的新方法:Array.prototype.includes()。这个方法解决了开发者在日常编码中一个常见需求——检查数组是否包含某个特定元素。本文将深入探讨 includes() 方法的特性、使用场景以及与类似方法的比较。

基本语法

includes() 方法的基本语法非常简单:

javascript 复制代码
arr.includes(valueToFind[, fromIndex])
  • valueToFind: 需要查找的元素值
  • fromIndex (可选): 从该索引处开始查找,默认为 0

方法返回一个布尔值,表示数组是否包含指定的元素。

精准匹配的特性

includes() 方法的核心特点是进行精准匹配,这意味着:

  1. 使用 SameValueZero 算法进行比较(与 === 类似,但认为 NaN 等于 NaN)
  2. 区分大小写(对于字符串)
  3. 考虑类型(不会进行类型转换)
javascript 复制代码
const arr = [1, 2, 3, NaN, 'hello'];

console.log(arr.includes(2));    // true
console.log(arr.includes(4));    // false
console.log(arr.includes(NaN));  // true (与 indexOf 不同)
console.log(arr.includes('Hello')); // false (区分大小写)

与 indexOf 的比较

includes() 出现之前,开发者通常使用 indexOf() 来检查元素是否存在:

javascript 复制代码
if (arr.indexOf(x) !== -1) {
  // 包含元素
}

includes() 相比 indexOf() 有几个优势:

  1. 语义更清晰,直接返回布尔值
  2. 能正确处理 NaN 的查找
  3. 代码更简洁

实际应用场景

1. 简单存在性检查

javascript 复制代码
const fruits = ['apple', 'banana', 'orange'];
if (fruits.includes('banana')) {
  console.log('We have bananas!');
}

2. 配置检查

javascript 复制代码
const allowedDomains = ['example.com', 'test.com', 'localhost'];
const currentDomain = window.location.hostname;

if (!allowedDomains.includes(currentDomain)) {
  alert('Access denied!');
}

3. 结合其他数组方法

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(n => [2, 4, 6, 8].includes(n));
// [2, 4]

注意事项

  1. 性能考虑:对于大型数组,includes() 是线性搜索 (O(n)),对于频繁查找,考虑使用 Set
  2. 对象比较:对于对象引用,比较的是引用而非内容
  3. 稀疏数组:对于稀疏数组中的空槽,includes() 会返回 false
javascript 复制代码
const obj1 = { id: 1 };
const obj2 = { id: 1 };
const arr = [obj1];

console.log(arr.includes(obj1)); // true
console.log(arr.includes(obj2)); // false

浏览器兼容性

Array.prototype.includes() 在大多数现代浏览器中都得到了支持,包括:

  • Chrome 47+
  • Firefox 43+
  • Edge 14+
  • Safari 9+
  • Node.js 6+

对于旧环境,可以使用 Babel 转译或 polyfill。

结论

Array.prototype.includes() 是 ES7 中一个看似简单但极其实用的新增功能。它提供了更直观、更可靠的方式来检查数组中是否包含某个元素,特别是在处理 NaN 时比传统的 indexOf() 方法更加准确。在日常开发中,当需要检查元素是否存在而不关心其具体位置时,includes() 应该是首选方法。