为什么DOM元素组成的数组可使用indexOf方法查找对应元素索引
问题描述
我知道indexOf无法在对象数组中使用,示例如下:
const objs = [ {name: 'darling', age: 28}, {name: 'eliot', age: 29} ] console.log(objs.indexOf({ name: 'eliot', age: 29 })) // 输出-1
但为什么由DOM元素组成的数组可以通过indexOf查找到对应元素的索引?示例如下:
document.getElementById('slides').addEventListener('click', function (e) { const nodes = document.querySelectorAll('#slides > .slide') const newNodes = [...nodes] console.log(newNodes); console.log(newNodes.indexOf(e.target)) // 可以输出对应索引 })
解答
Array.prototype.indexOf的匹配规则是严格相等(===),该运算对不同类型的值判断逻辑不同:
- 基础类型(字符串、数字、布尔值、null、undefined、Symbol):直接比较值是否一致
- 引用类型(普通对象、数组、函数、DOM节点等):比较两个变量存储的内存地址是否指向同一个实体
普通对象数组匹配失败的原因
你在indexOf参数中通过字面量语法声明的{ name: 'eliot', age: 29 }是全新的对象,会单独占用一块内存空间,和数组中已存储的同属性对象内存地址完全不同,严格相等判断不成立,所以返回-1,等价于以下逻辑:
const a = {name: 'eliot', age: 29} const b = {name: 'eliot', age: 29} console.log(a === b) // false
如果传入数组内原有对象的引用,就可以正常获取索引:
const objs = [ {name: 'darling', age: 28}, {name: 'eliot', age: 29} ] console.log(objs.indexOf(objs[1])) // 输出1
DOM数组匹配成功的原因
页面渲染完成后,每个DOM节点在内存中只会存在一份实体:
- 你通过
querySelectorAll获取的节点集合中,存储的是每个DOM节点的内存引用 - 点击事件回调中的
e.target就是触发点击的DOM节点本身的引用
二者指向同一个内存实体,严格相等判断成立,因此indexOf可以正常返回对应索引。
内容的提问来源于stack exchange,提问作者高欣平
相关产品推荐
相关产品推荐

