### includes():数组中快速查找元素的实用工具
在编程中,我们经常需要判断一个数组里是否包含某个特定元素。比如,检查用户选择的兴趣标签里有没有“阅读”,或者验证购物车中是否已添加某件商品。这时,`includes()` 方法就能派上用场——它是 JavaScript 数组自带的一个简单工具,专门用来完成这类“存在性检查”。
#### 一、includes() 是什么?
`includes()` 是数组对象的一个方法,作用是**检查数组中是否包含指定的元素**。它像一个“探测器”,遍历数组里的每个元素,一旦发现目标元素,就返回“找到了”(用 `true` 表示);如果找遍整个数组都没发现,就返回“没找到”(用 `false` 表示)。
这里的 `true` 和 `false` 是编程中的“布尔值”,即只有两种结果的逻辑值,分别表示“真”和“假”。
#### 二、怎么用 includes()?
使用 `includes()` 的语法很简单:
```javascript
数组名.includes(要查找的元素, 起始搜索位置);
```
- **第一个参数**(必选):要查找的目标元素,可以是数字、字符串、布尔值等基本类型,也可以是对象(但对象比较的是引用地址,稍后举例说明)。
- **第二个参数**(可选):从数组的哪个位置开始查找。默认是 `0`(即从第一个元素开始);如果传入负数,表示从数组末尾往前数第几个位置开始(比如 `-1` 表示从最后一个元素开始)。
#### 三、用例子看懂 includes()
假设我们有一个存储水果名称的数组:
```javascript
const fruits = ['苹果', '香蕉', '橙子', '草莓'];
```
**例1:基础用法(只传目标元素)**
检查数组里有没有“香蕉”:
```javascript
const hasBanana = fruits.includes('香蕉');
console.log(hasBanana); // 输出:true(因为数组里有“香蕉”)
```
检查有没有“西瓜”:
```javascript
const hasWatermelon = fruits.includes('西瓜');
console.log(hasWatermelon); // 输出:false(数组里没有“西瓜”)
```
**例2:指定起始搜索位置**
如果想从数组的第2个元素(索引为1,因为数组索引从0开始)开始查找“苹果”:
```javascript
const hasAppleFromIndex1 = fruits.includes('苹果', 1);
console.log(hasAppleFromIndex1); // 输出:false(从第2个元素“香蕉”开始找,“苹果”在前面,所以没找到)
```
如果用负数指定起始位置,比如从倒数第2个元素(索引为2,即“橙子”)开始找“草莓”:
```javascript
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` 时会失效:
```javascript
const numbers = [1, NaN, 3];
console.log(numbers.indexOf(NaN)); // 输出:-1(没找到,因为 NaN 不等于自身)
```
但 `includes()` 能正确识别 `NaN`:
```javascript
console.log(numbers.includes(NaN)); // 输出:true(成功找到 NaN)
```
#### 五、注意:对象比较的是“引用”
如果数组里存的是对象(比如 `{ name: '小明' }`),`includes()` 会比较对象的“引用地址”,而不是内容。也就是说,即使两个对象的内容完全一样,只要它们是独立创建的,就会被判定为不同元素。
例:
```javascript
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:基础类型去重(数字、字符串)
原数组包含重复数字和字符串:
```javascript
const originalArr = [2, 3, 2, 'a', 'b', 'a', 5];
```
用 `includes()` 实现去重:
```javascript
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`:
```javascript
const arrWithNaN = [1, NaN, 2, NaN, 'x', 'x'];
const uniqueWithNaN = uniqueArray(arrWithNaN);
console.log(uniqueWithNaN); // 输出:[1, NaN, 2, 'x'](重复的 NaN 和 'x' 被去掉,保留一个 NaN)
```
##### 注意:对象去重的局限性
如前所述,`includes()` 对对象的比较依赖“引用地址”。如果两个对象内容相同但引用不同,去重时会视为不同元素。例如:
```javascript
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()`,让代码更简洁高效。
includes():数组中快速查找元素的实用工具
2 分钟阅读
252 字
如果文章对您有帮助,欢迎支持作者继续创作