在编程中,我们经常需要判断一个数组里是否包含某个特定元素。比如,检查用户选择的兴趣标签里有没有“阅读”,或者验证购物车中是否已添加某件商品。这时,includes() 方法就能派上用场——它是 JavaScript 数组自带的一个简单工具,专门用来完成这类“存在性检查”。

一、includes() 是什么?

includes() 是数组对象的一个方法,作用是检查数组中是否包含指定的元素。它像一个“探测器”,遍历数组里的每个元素,一旦发现目标元素,就返回“找到了”(用 true 表示);如果找遍整个数组都没发现,就返回“没找到”(用 false 表示)。

这里的 truefalse 是编程中的“布尔值”,即只有两种结果的逻辑值,分别表示“真”和“假”。

二、怎么用 includes()?

使用 includes() 的语法很简单:

数组名.includes(要查找的元素, 起始搜索位置);  
  • 第一个参数(必选):要查找的目标元素,可以是数字、字符串、布尔值等基本类型,也可以是对象(但对象比较的是引用地址,稍后举例说明)。
  • 第二个参数(可选):从数组的哪个位置开始查找。默认是 0(即从第一个元素开始);如果传入负数,表示从数组末尾往前数第几个位置开始(比如 -1 表示从最后一个元素开始)。

三、用例子看懂 includes()

假设我们有一个存储水果名称的数组:

const fruits = ['苹果', '香蕉', '橙子', '草莓'];  

例1:基础用法(只传目标元素)
检查数组里有没有“香蕉”:

const hasBanana = fruits.includes('香蕉');  
console.log(hasBanana); // 输出:true(因为数组里有“香蕉”)  

检查有没有“西瓜”:

const hasWatermelon = fruits.includes('西瓜');  
console.log(hasWatermelon); // 输出:false(数组里没有“西瓜”)  

例2:指定起始搜索位置
如果想从数组的第2个元素(索引为1,因为数组索引从0开始)开始查找“苹果”:

const hasAppleFromIndex1 = fruits.includes('苹果', 1);  
console.log(hasAppleFromIndex1); // 输出:false(从第2个元素“香蕉”开始找,“苹果”在前面,所以没找到)  

如果用负数指定起始位置,比如从倒数第2个元素(索引为2,即“橙子”)开始找“草莓”:

const hasStrawberryFromNegative = fruits.includes('草莓', -2);  
// 数组长度4,-2 对应索引 4-2=2(即第三个元素“橙子”),从“橙子”开始找  
console.log(hasStrawberryFromNegative); // 输出:true(“橙子”后面有“草莓”)  

四、includes() 的特殊能力:识别 NaN

在 JavaScript 中,NaN(Not a Number)是一个特殊的数值,表示“不是一个有效的数字”。有趣的是,NaN 有个奇怪的特性:NaN === NaN 的结果是 false(即它不等于自身)。

这导致用传统方法(如 indexOf())查找 NaN 时会失效:

const numbers = [1, NaN, 3];  
console.log(numbers.indexOf(NaN)); // 输出:-1(没找到,因为 NaN 不等于自身)  

includes() 能正确识别 NaN

console.log(numbers.includes(NaN)); // 输出:true(成功找到 NaN)  

五、注意:对象比较的是“引用”

如果数组里存的是对象(比如 { name: '小明' }),includes() 会比较对象的“引用地址”,而不是内容。也就是说,即使两个对象的内容完全一样,只要它们是独立创建的,就会被判定为不同元素。

例:

const obj1 = { id: 1 };  
const obj2 = { id: 1 }; // 内容和 obj1 一样,但这是新对象  
const arr = [obj1];  

console.log(arr.includes(obj1)); // 输出:true(同一个对象,引用相同)  
console.log(arr.includes(obj2)); // 输出:false(不同对象,引用不同)  

六、和 indexOf() 的区别

你可能听过另一个数组方法 indexOf(),它也能查找元素,但和 includes() 有明显区别:

  • includes() 返回布尔值(true/false),直接告诉你“有没有”;
  • indexOf() 返回元素的索引(位置),如果没找到则返回 -1

如果只需要判断“是否存在”,用 includes() 更直观;如果需要知道“在哪里”,用 indexOf()

七、用 includes() 实现数组去重

数组去重是编程中常见的需求:去掉数组中重复出现的元素,只保留唯一的元素。利用 includes() 的“存在性检查”能力,可以轻松实现这一功能。

去重思路
  1. 创建一个空数组(称为“结果数组”),用于存放去重后的元素;
  2. 遍历原数组中的每个元素;
  3. 对每个元素,用 includes() 检查结果数组中是否已存在该元素;
  4. 如果不存在,就将该元素添加到结果数组;
  5. 遍历结束后,结果数组就是去重后的数组。
实例1:基础类型去重(数字、字符串)

原数组包含重复数字和字符串:

const originalArr = [2, 3, 2, 'a', 'b', 'a', 5];  

includes() 实现去重:

function uniqueArray(arr) {  
  const result = []; // 创建空结果数组  
  for (let i = 0; i < arr.length; i++) {  
    const current = arr[i];  
    // 检查结果数组是否已有当前元素  
    if (!result.includes(current)) {  
      result.push(current); // 没有则添加  
    }  
  }  
  return result;  
}  

const uniqueArr = uniqueArray(originalArr);  
console.log(uniqueArr); // 输出:[2, 3, 'a', 'b', 5](重复的2和'a'被去掉)  
实例2:包含 NaN 的去重

由于 includes() 能识别 NaN,去重时可保留一个 NaN

const arrWithNaN = [1, NaN, 2, NaN, 'x', 'x'];  
const uniqueWithNaN = uniqueArray(arrWithNaN);  
console.log(uniqueWithNaN); // 输出:[1, NaN, 2, 'x'](重复的 NaN 和 'x' 被去掉,保留一个 NaN)  
注意:对象去重的局限性

如前所述,includes() 对对象的比较依赖“引用地址”。如果两个对象内容相同但引用不同,去重时会视为不同元素。例如:

const objA = { id: 1 };  
const objB = { id: 1 }; // 内容与 objA 相同,但引用不同  
const arrWithObj = [objA, objB, objA];  

const uniqueObjArr = uniqueArray(arrWithObj);  
console.log(uniqueObjArr); // 输出:[objA, objB](objA 被保留一次,objB 因引用不同而被视为新元素)  

因此,对象去重需额外处理(如转为字符串比较),这里暂不展开。

总结

includes() 是数组操作中非常实用的工具,核心功能是判断元素是否存在,语法简单、结果明确。记住它的特点:

  • 返回布尔值(true 表示存在,false 表示不存在);
  • 支持指定起始搜索位置(正数从左数,负数从右数);
  • 能正确识别 NaN,但对象比较依赖引用地址;
  • 可结合循环实现数组去重,尤其适合基础类型数组。

下次需要检查数组元素是否存在,或给数组去重时,不妨试试 includes(),让代码更简洁高效。