js数组中indexOf和findIndex的区别

这篇博客探讨了JavaScript数组方法indexOf和findIndex的区别。indexOf通过元素值进行查找,而findIndex允许传递自定义函数,提供更灵活的查找方式。findIndex在适用范围上更为广泛,可以实现忽略大小写、类型转换以及查找引用类型相等的元素等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. indexOf

语法

arr.indexOf(searchElement[, fromIndex])

参数

searchElement  要查找的元素

fromIndex (可选 )  开始查找的位置

如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-1表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.

返回值

首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1

2. findIndex

语法

arr.findIndex(callback[, thisArg])

参数

callback (element, index, array

针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:

  element 当前元素。

  index  当前元素的索引。

  array  调用findIndex的数组。

thisArg

可选。执行callback时作为this对象的值.

返回值

数组中通过提供测试函数的第一个元素的索引。否则,返回-1

3. 两者之间的区别

(1) 使用方式

  indexOf传入参数为待查找元素,findIndex传入参数为自定义函数

(2)适用范围

  虽然indexOf与findIndex都可用以查找元素,但findIndex比indexOf使用更灵活,适用范围更广

  例如,我们可以自定义findIndex的查找函数,使其查找值时忽略大小写、强转类型比较,甚至可以查找值相同的引用类型,以下举例详细说明

a. 忽略大小写

const arr = [1, '2', 'Test', { a: 1 }]
const findVal = 'test'

console.log(arr.indexOf(findVal)) // -1
console.log(arr.findIndex(val => {
    if (val.toLowerCase && findVal.toLowerCase) return val.toLowerCase() === findVal.toLowerCase()
    return val === findVal
})) // 2

b. 类型强转

const arr = [1, '2', 'Test', { a: 1 }]
const findVal = 2

console.log(arr.indexOf(findVal)) // -1
console.log(arr.findIndex(val => val == findVal)) // 1

c. 查找值相同的引用类型

const arr = [1, '2', 'Test', { a: 1 }]
const findVal = { a: 1 }

console.log(arr.indexOf(findVal)) // -1
console.log(arr.findIndex(val => compare(val, findVal))) // 3
  
/**
 * @name 两值比较
 * @param {*} obj1 值1
 * @param {*} obj2 值2
 * @returns {Boolean} true 相等 false 不等
 */
export function compare (obj1, obj2) {
  const type = getDataType(obj1)
  if (type !== getDataType(obj2)) return false

  if (typeof obj1 !== 'object' || obj1 === null) return obj1 === obj2

  // Set类型, Map类型, 转化为数组
  if (type === 'set' || type === 'map') {
    obj1 = Array.from(obj1)
    obj2 = Array.from(obj2)
  }

  const obj1_keys = Object.keys(obj1)
  const obj2_keys = Object.keys(obj2)
  if (obj1_keys.length !== obj2_keys.length) return false
  
  return obj1_keys.every(k =>  compare(obj1[k], obj2[k]))
}

/**
 * @name 获取数据类型
 * @param {*} val 数据
 * @returns {String} 数据类型
 * boolean 布尔值, number 数, string 字符串,
 * undefined, null, array 数组, object 对象,
 * function 函数, symbol, set Set类型, map Map类型
 */
export function getDataType (val) {
  const rules = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Array]': 'array',
    '[object Object]': 'object',
    '[object Function]': 'function',
    '[object Symbol]': 'symbol',
    '[object Set]': 'set',
    '[object Map]': 'map'
  }

  return rules[Object.prototype.toString.call(val)]
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值