用 JavaScript 的 Array.includes () 替代 indexOf,代码可读性飙升

在 JavaScript 数组操作中,判断元素是否存在是常见需求,indexOf 和 includes () 是常用方法。本文先概述两者功能,重点阐述用 includes () 替代 indexOf 的优势:includes () 返回布尔值,直观反映元素是否存在,无需额外判断,大幅提升代码可读性;还支持处理 NaN 等特殊值,使用更便捷。同时介绍两者区别、includes () 使用场景与示例,助开发者掌握这一优化代码的技巧,让代码更清晰易维护。​

一、引言:数组元素判断的常见需求​

在 JavaScript 编程中,数组是一种非常重要的数据结构,我们经常需要对数组进行各种操作,其中判断某个元素是否存在于数组中是一项极为常见的需求。无论是在表单验证中检查用户输入的选项是否在允许的范围内,还是在数据处理中筛选特定元素,都离不开这样的判断操作。​

以往,很多开发者习惯使用 indexOf 方法来实现这一功能。indexOf 方法返回元素在数组中首次出现的索引,如果元素不存在则返回 - 1。因此,开发者需要通过判断返回值是否不等于 - 1 来确定元素是否存在。然而,这种方式在代码表达上不够直观,对于新手开发者来说,可能需要额外的理解成本,而且在阅读代码时,也需要多一步的逻辑转换,一定程度上影响了代码的可读性。​

随着 JavaScript 的发展,ES2016(ES7)引入了 Array.includes () 方法,它的出现为判断数组元素是否存在提供了一种更简洁、更直观的方式。includes () 方法直接返回一个布尔值,存在则返回 true,不存在则返回 false,这种返回结果能够直接反映我们想要的判断结果,极大地提升了代码的可读性。本文将详细介绍为什么要用 Array.includes () 替代 indexOf,以及它们之间的区别、includes () 的使用场景等内容。​

二、indexOf 方法的使用与局限​

(一)indexOf 方法的基本使用​

indexOf 方法用于查找数组中某个元素首次出现的位置,其语法为:array.indexOf(searchElement[, fromIndex])。其中,searchElement是要查找的元素,fromIndex是可选参数,表示从数组的哪个索引位置开始查找,默认值为 0。​

当找到元素时,indexOf 返回该元素在数组中的索引;如果没有找到,則返回 - 1。例如:​

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

console.log(fruits.indexOf('banana')); // 输出1​

console.log(fruits.indexOf('grape')); // 输出-1​

console.log(fruits.indexOf('apple', 1)); // 输出3​

在实际应用中,开发者通常会这样使用 indexOf 来判断元素是否存在:​

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

if (numbers.indexOf(3) !== -1) {​

console.log('3存在于数组中');​

} else {​

console.log('3不存在于数组中');​

}​

(二)indexOf 方法的局限​

虽然 indexOf 方法能够实现判断元素是否存在的功能,但它存在一些明显的局限:​

  1. 返回值不直观:indexOf 返回的是元素的索引或 - 1,这并不是直接的判断结果。开发者需要通过!== -1这样的条件来转换为布尔值判断,这增加了代码的理解难度,尤其是对于刚接触 JavaScript 的开发者来说,可能会对这种写法感到困惑。​
  1. 对 NaN 的处理不准确:在 JavaScript 中,NaN(Not a Number)是一个特殊的值,它与自身不相等(NaN === NaN的结果为 false)。indexOf 方法在判断数组中是否包含 NaN 时,会出现错误的结果。例如:​

const arr = [1, 2, NaN, 4];​

console.log(arr.indexOf(NaN)); // 输出-1,实际数组中包含NaN​

这种对 NaN 处理的缺陷,使得 indexOf 在某些场景下无法正确完成元素判断的任务。​

  1. 语义不明确:从方法的名称来看,indexOf 的主要功能是获取元素的索引,而不是判断元素是否存在。用它来进行元素存在性判断,在语义上不够明确,会让其他阅读代码的开发者需要花费更多的时间去理解代码的意图。​

三、Array.includes () 方法的优势​

(一)includes () 方法的基本使用​

Array.includes () 方法是 ES2016 引入的新方法,专门用于判断数组中是否包含某个元素,其语法为:array.includes(searchElement[, fromIndex])。参数与 indexOf 类似,searchElement是要查找的元素,fromIndex是可选的起始查找索引,默认值为 0。​

includes () 方法的返回值是布尔值,当数组中包含该元素时返回 true,否则返回 false。例如:​

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

console.log(colors.includes('green')); // 输出true​

console.log(colors.includes('yellow')); // 输出false​

console.log(colors.includes('red', 1)); // 输出true​

用 includes () 来判断元素是否存在的代码如下:​

const animals = ['dog', 'cat', 'bird'];​

if (animals.includes('cat')) {​

console.log('cat存在于数组中');​

} else {​

console.log('cat不存在于数组中');​

}​

这种写法直接根据返回的布尔值进行判断,非常直观。​

(二)includes () 方法的优势​

相比 indexOf 方法,includes () 方法具有以下显著优势:​

  1. 返回值直观,提升代码可读性:includes () 直接返回布尔值,开发者可以直接根据返回结果进行判断,无需进行额外的转换。这种直观的返回值使得代码的逻辑更加清晰,其他开发者在阅读代码时能够快速理解其意图,大大提升了代码的可读性。​

例如,同样是判断元素是否存在,使用 includes () 的代码:​

if (fruits.includes('apple')) { ... }​

比使用 indexOf 的代码:​

if (fruits.indexOf('apple') !== -1) { ... }​

更加简洁明了,一眼就能看出是在判断数组中是否包含 'apple' 这个元素。​

  1. 正确处理 NaN:includes () 方法能够正确判断数组中是否包含 NaN,这解决了 indexOf 方法的一大缺陷。例如:​

const nums = [3, NaN, 7];​

console.log(nums.includes(NaN)); // 输出true​

这使得 includes () 在处理包含 NaN 的数组时更加可靠。​

  1. 语义明确:includes () 从名称上就清晰地表达了它的功能是判断数组是否包含某个元素,使用它来进行元素存在性判断,符合代码的语义化要求,让代码更易于理解和维护。​

四、indexOf 与 includes () 的其他区别​

除了上述提到的返回值、对 NaN 的处理和语义方面的区别外,indexOf 和 includes () 在其他一些细节上也存在差异:​

  1. 对稀疏数组的处理:在 JavaScript 中,稀疏数组是指包含空槽(empty slot)的数组。indexOf 会将空槽视为 undefined,而 includes () 则会跳过空槽,不将其视为 undefined。例如:​

  1. 兼容性:indexOf 是 ES5 中引入的方法,兼容性较好,几乎所有的现代浏览器和旧版本浏览器(如 IE9 及以上)都支持它。而 includes () 是 ES2016 引入的,在一些较旧的浏览器(如 IE)中不支持。如果需要兼容这些旧浏览器,使用 includes () 时需要进行 polyfill 处理。​

不过,随着前端开发中对旧浏览器支持需求的逐渐降低,以及 Babel 等转译工具的广泛使用,includes () 的兼容性问题已经不再是主要障碍。​

五、includes () 的使用场景与示例​

(一)表单验证​

在表单验证中,经常需要判断用户输入的选项是否在允许的范围内。例如,判断用户选择的省份是否在预设的省份列表中:​

使用 includes () 使得判断逻辑清晰明了,易于理解。​

(二)权限判断​

在权限管理中,判断用户是否拥有某个特定权限:​

const userPermissions = ['read', 'write', 'delete'];​

const requiredPermission = 'admin';​

if (userPermissions.includes(requiredPermission)) {​

console.log('用户拥有该权限');​

} else {​

console.log('用户没有该权限');​

}​

(三)数据筛选​

在数据处理中,筛选出包含特定元素的数组项。例如,筛选出包含 'tag1' 标签的数据:​

const data = [​

{ id: 1, tags: ['tag1', 'tag2'] },​

{ id: 2, tags: ['tag3', 'tag4'] },​

{ id: 3, tags: ['tag1', 'tag5'] }​

];​

const filteredData = data.filter(item => item.tags.includes('tag1'));​

console.log(filteredData); ​

// 输出[{ id: 1, tags: ['tag1', 'tag2'] }, { id: 3, tags: ['tag1', 'tag5'] }]​

(四)避免重复添加​

在向数组中添加元素时,避免添加重复的元素:​

let items = ['item1', 'item2', 'item3'];​

const newItem = 'item2';​

if (!items.includes(newItem)) {​

items.push(newItem);​

}​

console.log(items); // 输出['item1', 'item2', 'item3'],没有重复添加​

六、总结归纳​

通过对 JavaScript 中的 Array.indexOf () 和 Array.includes () 方法的详细介绍和对比,我们可以清晰地看到,includes () 方法在判断数组元素是否存在方面具有显著的优势。​

indexOf 方法虽然能够实现功能,但它返回索引值的特性导致代码不够直观,对 NaN 的处理不准确,语义也不够明确。而 includes () 方法直接返回布尔值,使得代码逻辑更加清晰,可读性大幅提升;它能够正确处理 NaN,增强了方法的可靠性;同时,其名称也明确表达了判断元素是否存在的语义,符合代码语义化的要求。​

在实际开发中,除了需要兼容非常旧的浏览器(如 IE)的场景外,我们应该优先使用 includes () 方法来判断数组中是否包含某个元素。这不仅能让我们的代码更加简洁、易懂,还能减少因对 indexOf 理解不当而产生的 bug,提高开发效率和代码质量。​

随着 JavaScript 语言的不断发展,更多便捷、高效的方法会被引入,作为开发者,我们应该及时学习和掌握这些新特性,不断优化自己的代码,提升开发水平。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值