在JavaScript里判断一个值是否存在于数组中,原生方法有 indexOf(),也有更现在的 includes()。但在jQuery的工具库中,$.inArray() 是一个容易被忽视却很实用的存在。它的职责很专一:在给定的数组中搜索某个特定值,找到了就返回它的索引位置,找不到就返回 -1。
核心返回值:索引位置或 -1
jQuery.inArray() 的逻辑非常清晰。它不会修改原数组,也从不返回布尔值。它的返回值只有两种可能:
-
找到匹配项时,返回该元素在数组中的索引值(从0开始计数)。
-
没有找到时,返回 -1。
如果数组中存在多个相同的值,它只返回第一次出现的那个索引位置。这和原生 indexOf() 的行为保持一致。
为什么不用原生的 indexOf() 或 includes()?
可能有读者会问,既然现在浏览器都支持 Array.prototype.indexOf(),为什么还需要 $.inArray()?这里讲一点我的实际经验。
$.inArray() 在jQuery 1.2版本就引入了,那会儿原生 indexOf() 在IE8及以下浏览器里根本不存在。jQuery把这个方法封装起来,就是为了抹平浏览器间的兼容性差异,给开发者一个统一可靠的API。
在维护老的jQuery项目时,代码风格的一致性是有价值的。一个文件里其他部分都在用 $.extend()、$.each() 等jQuery工具方法,到了数组查找突然跳出一个原生的 indexOf(),读起来会有些割裂。如果是全新项目并且不依赖jQuery,那直接使用原生方法没问题。这是一个项目语境下的选择,不存在绝对的优劣。
语法与参数详解
jQuery.inArray(val, arr [, index])
这个语法看着简单,但第三个参数隐藏着一个容易被忽略的功能点。
参数说明:
-
val:要搜索的值。这是你要在数组中寻找的那个目标项。
-
arr:被搜索的目标数组。
inArray()会在这个数组中进行遍历查找。 -
index(可选):指定从数组的哪个索引位置开始搜索。传入这个参数后,查找范围不再是整个数组,而是从该位置往后的那段。如果不传,默认从头开始。
关于第三个参数有个需要留心的地方:它不是限定搜索范围,而是指定搜索的起点。也就是说,它跳过了前面的元素,只看后半段。
实战示例一:基础查找,定位用户列表中的角色
这个例子模拟一个实际的场景——在一个用户角色列表中查找某个特定角色是否已存在。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery.inArray() 基础查找</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h2>角色权限校验</h2>
<p id="array-display"></p>
<p id="search-target"></p>
<button id="searchBtn">查找角色</button>
<p id="search-result"></p>
<script>
$(document).ready(function(){
// 当前系统的用户角色列表
var roles = ["普通用户", "编辑", "审核员", "管理员", "编辑", "访客"];
var targetRole = "编辑";
$("#array-display").html("<b>当前角色列表: </b>[" + roles.join(", ") + "]");
$("#search-target").html("<b>要查找的角色: </b>" + targetRole);
$("#searchBtn").click(function(){
var position = jQuery.inArray(targetRole, roles);
if(position !== -1){
// 找到了,注意:编辑出现了两次,但返回的是第一次出现的索引
$("#search-result").html("角色 <b>" + targetRole + "</b> 首次出现在索引 <b>" + position + "</b> 的位置(从0开始计数)。");
} else {
$("#search-result").html("角色 <b>" + targetRole + "</b> 不存在于列表中。");
}
});
});
</script>
</body>
</html>
这里值得关注的是,数组里"编辑"出现了两次,分别在索引1和索引4,但 inArray() 返回的是 1,验证了它只返回第一次匹配位置的特性。
实战示例二:指定起始索引,跳过已处理的数据
这个例子展示第三个参数的实际用途。假设我们有一个日志数据数组,已经处理了前面的部分,现在要从指定位置开始检查某条记录是否还在后续数据中出现。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery.inArray() 指定起始位置</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h2>跳过已处理数据进行搜索</h2>
<p id="array-display2"></p>
<p id="search-config"></p>
<button id="searchBtn2">从索引起点4开始查找</button>
<p id="search-result2"></p>
<script>
$(document).ready(function(){
// 一批设备状态码
var statusCodes = ["OFF", "ON", "OFF", "ERROR", "READY", "ON", "OFF", "ON"];
var searchCode = "OFF";
var startIndex = 4;
$("#array-display2").html("<b>状态码序列: </b>[" + statusCodes.join(", ") + "]");
$("#search-config").html("<b>查找目标: </b>" + searchCode + " | <b>起始索引: </b>" + startIndex);
$("#searchBtn2").click(function(){
var position = jQuery.inArray(searchCode, statusCodes, startIndex);
if(position !== -1){
$("#search-result2").html("从索引" + startIndex + "开始查找,<b>" + searchCode + "</b> 出现在索引 <b>" + position + "</b>。");
} else {
$("#search-result2").html("从索引" + startIndex + "开始查找,未找到 <b>" + searchCode + "</b>(注意:前面即使有匹配也会被跳过)。");
}
});
});
</script>
</body>
</html>
这个例子中,"OFF"在数组里出现了三次(索引0、2、6)。但我们指定从索引4开始查找,前两个就被跳过了,最终命中的是索引6。如果把目标改成在前半段就结束出现的值,返回值就会是 -1。个人在开发中曾用它来实现一个简单的去重检查循环——每次找到一个目标后,下一次就从该位置的下一索引开始继续搜,直到返回 -1 为止。
本节课程知识要点
-
jQuery.inArray()用于在数组中定位一个值,找到返回索引值(从0开始),找不到返回 -1。它不会影响原数组。 -
当数组中有多个相同元素时,该方法只会返回第一次出现对应的索引位置。
-
第三个可选参数
index的作用是设定搜索的起始位置,不是限定搜索范围。从指定索引起往后的部分查找,前面的元素会被忽略。 -
jQuery.inArray()在行为上等价于原生JavaScript的Array.prototype.indexOf(),在旧版浏览器的兼容性场景或统一项目代码风格时仍有使用的价值。 -
如果需要做复杂的数组对象查找(例如按对象的某个属性查找),
inArray()无法直接胜任,因为它做的是值的严格匹配,不适用于对象类型的元素比较。