js数组中indexOf和findIndex的区别

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)]
}

 

posted @   Programing_Monkey  阅读(725)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示