JavaScript的Array.prototype.includes方法是什么?怎么用?

来源:AI社区作者:广州GEO公司头衔:草根站长
导读:本期聚焦于广州GEO公司创作的《JavaScript的Array.prototype.includes方法是什么?怎么用?》,敬请观看详情。Array.prototype.includes是JavaScript中用于判断数组是否包含指定元素的方法,是ES6新增的数组原型方法。很多开发者在需要判断数组中是否存在某个值时,会考虑使用这个方法,但对其具体用法和注意事项并不清楚。本文将详细介绍includes方法的定义、基本语法、参数含义,同时对比它和indexOf方法的区别,还会讲解它处理NaN、空位等特殊场景的表现,最后给出实际开发中的使用示例,帮助开发者快速掌握这个方法的用法。

Array.prototype.includes 是 JavaScript 数组原型上的一个方法,用于判断当前数组是否包含某个指定值。它的返回值是一个布尔值:如果找到目标值就返回 true,没有找到就返回 false。相比过去常见的 indexOf 判断方式,includes 的语义更加直接,代码读起来更接近自然语言表达,特别适合用于权限判断、状态判断、标签判断等“是否包含”的场景。

includes 方法的基本语义与语法结构

Array.prototype.includes 的核心作用非常明确:判断数组中是否存在某个值。调用这个方法时,数组本身是调用者,传入的第一个参数是要查找的目标值。方法执行后不会修改原数组,只会返回一个布尔结果。这种设计使它非常适合用于条件判断,不需要再额外处理索引值,也不需要手动比较返回值是否等于某个特殊数字。

它的语法可以写成 arr.includes(searchElement, fromIndex)。其中,searchElement 是必填参数,表示要查找的值;fromIndex 是可选参数,表示从数组的哪个位置开始查找。如果没有提供第二个参数,默认从索引 0 开始,也就是从数组头部一直查找到尾部。如果 fromIndex 大于或等于数组长度,方法会直接返回 false,因为此时已经没有可查找的范围。

fromIndex 是负数时,它会从数组末尾向前计算起始位置。例如,传入 -1 表示从最后一个元素开始查找,传入 -2 表示从倒数第二个元素开始查找。需要注意的是,负数参数改变的是查找起点,查找方向仍然是从该起点向数组末尾进行。理解这一点,可以避免误以为负数索引会反向遍历数组。

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

// 查找普通元素
console.log(fruits.includes('banana')); // true
console.log(fruits.includes('grape')); // false

// fromIndex 表示开始查找的位置
console.log(fruits.includes('apple', 1)); // false
console.log(fruits.includes('banana', 1)); // true

// 负数 fromIndex 从数组末尾向前计算
console.log(fruits.includes('cherry', -1)); // true
console.log(fruits.includes('apple', -2)); // false

常见使用场景与容易忽略的边界情况

在实际开发中,includes 最常见的用途是判断某个值是否存在于一组候选值中。例如,判断用户角色是否包含管理员,判断当前页面状态是否属于可编辑状态,或者判断请求返回的标签列表中是否包含某个关键词。由于它返回布尔值,直接放在 if 条件中非常自然,不需要像过去那样写 indexOf 后再与 -1 比较。

另一个常见场景是利用第二个参数控制查找范围。比如数组中可能存在重复值,而我们只关心某个位置之后是否仍然存在目标值,就可以通过 fromIndex 跳过前面的元素。这个能力在分页数据检查、序列校验、重复项判断等场景中很有用。虽然它不会返回具体位置,但对于只关心“有没有”的需求来说,已经足够清晰。

不过,includes 也有一些需要特别注意的边界情况。首先是稀疏数组。如果数组中存在空位,includes 会把这些空位当作 undefined 来处理。因此,当数组中确实存在空位时,查找 undefined 可能返回 true。其次是对象类型的比较。includes 判断对象时比较的是引用地址,而不是对象内部的属性内容。两个结构相同的对象,如果不是同一个引用,也会被认为不相等。

const permissions = ['read', 'write'];

if (permissions.includes('write')) {
  console.log('允许编辑');
}

const statuses = ['pending', 'reviewing', 'published'];
console.log(statuses.includes('reviewing')); // true
console.log(statuses.includes('archived')); // false

// 从指定位置开始查找
const ids = [101, 102, 103, 102];
console.log(ids.includes(102, 2)); // true
console.log(ids.includes(101, 2)); // false
// 稀疏数组中的空位会被当作 undefined 处理
const sparseList = ['a', , 'c'];
console.log(sparseList.includes(undefined)); // true
console.log(sparseList.includes('b')); // false

// 对象比较的是引用地址,而不是对象内容
const config = { mode: 'dark' };
const list = [config];

console.log(list.includes(config)); // true
console.log(list.includes({ mode: 'dark' })); // false

includes 与 indexOf 的差异以及兼容思路

includes 出现之前,很多开发者会使用 indexOf 来判断数组是否包含某个值。典型写法是先获取索引,再判断索引是否不等于 -1。这种写法虽然可以完成任务,但语义上更像是在询问“这个值在哪里”,而不是“这个值是否存在”。当业务只关心是否存在时,includes 显然更贴近意图。

两者更重要的差异体现在对特殊值的处理上。includes 使用 SameValueZero 算法进行比较,这种算法在大多数情况下与严格相等类似,但它认为两个 NaN 是相等的。而 indexOf 的判断思路更接近严格相等,由于 NaN 不等于自身,所以 indexOf(NaN) 通常无法正确找到 NaN。这一点在处理数值校验、异常值判断时尤其重要。

对比项includes 方法indexOf 方法
返回值类型布尔值,直接表达是否包含数字,返回索引位置,未找到时返回 -1
对 NaN 的处理可以正确识别 NaN无法正确识别 NaN
代码语义更适合表达“是否存在”更适合表达“位置在哪里”
比较方式使用 SameValueZero 算法更接近严格相等判断
const values = [10, NaN, 20];

// includes 可以识别 NaN
console.log(values.includes(NaN)); // true

// indexOf 对 NaN 不友好
console.log(values.indexOf(NaN)); // -1

// 写法可读性对比
if (values.includes(10)) {
  console.log('包含 10');
}

if (values.indexOf(10) !== -1) {
  console.log('包含 10');
}

从使用建议来看,如果只需要判断数组是否包含某个值,优先使用 includes 通常会让代码更简洁。如果除了判断是否存在,还需要拿到目标值第一次出现的位置,那么 indexOf 仍然有它的价值。换句话说,两者并不是简单替代关系,而是分别服务于不同的查询目的。

另外,在当下大多数 JavaScript 运行环境中,Array.prototype.includes 已经可以被直接使用。但如果项目需要兼容一些较旧的浏览器环境,可以通过 polyfill 手动补齐这个方法。下面的示例实现了一个基础兼容方案,重点模拟了起始索引计算以及对 NaN 的判断逻辑。

if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function (searchElement, fromIndex) {
      if (this == null) {
        throw new TypeError('this is null or not defined');
      }

      var target = Object(this);
      var length = target.length >>> 0;

      if (length === 0) {
        return false;
      }

      var start = fromIndex | 0;
      var index = start >= 0 ? start : Math.max(length - Math.abs(start), 0);

      // SameValueZero:普通严格相等,并认为两个 NaN 相等
      function sameValueZero(x, y) {
        return x === y || (x !== x && y !== y);
      }

      while (index < length) {
        if (sameValueZero(target[index], searchElement)) {
          return true;
        }
        index++;
      }

      return false;
    }
  });
}

总体而言,Array.prototype.includes 是一个语义清晰、使用频率很高的数组方法。它的优势在于直接返回布尔结果,并且能够正确处理 NaN 这类特殊值。在使用时,只要理解 fromIndex 的起始位置规则、稀疏数组空位的处理方式,以及对象比较基于引用地址这几个关键点,就能在大多数数组包含判断场景中安全、自然地使用它。

Array.prototype.includesJavaScript数组方法数组查找ES6新特性includes用法修改时间:2026-06-29 02:36:17

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。