lodash里的indexOf方法

166 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情

前言

indexOf方法可以使用SameValueZero 等值比较,返回首次 value 在数组array中被找到的索引值,如果fromIndex为负值,将从数组array尾端索引进行匹配。

使用如下:

_.indexOf([1, 2, 1, 2], 2);
// => 1
 
// Search from the `fromIndex`.
_.indexOf([1, 2, 1, 2], 2, 2);
// => 3

indexOf方法方法实现上需要借助两个内部方法,即核心方法baseIndexOf和参数处理调用的toInteger方法。

baseIndexOf

baseIndexOf方法实现上先对参数进行判断,如果是NaN的情况则调用baseFindIndex方法,正常数据则调用strictIndexOf方法。

源码如下:

import baseFindIndex from './_baseFindIndex.js';
import baseIsNaN from './_baseIsNaN.js';
import strictIndexOf from './_strictIndexOf.js';

function baseIndexOf(array, value, fromIndex) {
  return value === value
    ? strictIndexOf(array, value, fromIndex)
    : baseFindIndex(array, baseIsNaN, fromIndex);
}

baseIsNaN

baseIsNaN方法判断值为NaN的数据。

源码如下:

function baseIsNaN(value) {
  return value !== value;
}

strictIndexOf

strictIndexOf方法采用===严格比较,通过while遍历数组。

源码如下:

function strictIndexOf(array, value, fromIndex) {
  var index = fromIndex - 1,
      length = array.length;

  while (++index < length) {
    if (array[index] === value) {
      return index;
    }
  }
  return -1;
}

baseFindIndex

baseFindIndex方法同为lodash里的内部方法,主要是查找数组目标项的索引值。

源码如下:

function baseFindIndex(array, predicate, fromIndex, fromRight) {
  var length = array.length,
      index = fromIndex + (fromRight ? 1 : -1);

  while ((fromRight ? index-- : ++index < length)) {
    if (predicate(array[index], index, array)) {
      return index;
    }
  }
  return -1;
}

toInteger

toInteger方法的实现我们在《 lodash里to系列之如何将数据转换成数字类型 》中了解到其内部实现,这里不多做赘述。

源码实现

indexOf方法的源码实现如下:

import baseIndexOf from './_baseIndexOf.js';
import toInteger from './toInteger.js';

var nativeMax = Math.max;

function indexOf(array, value, fromIndex) {
  var length = array == null ? 0 : array.length;
  if (!length) {
    return -1;
  }
  var index = fromIndex == null ? 0 : toInteger(fromIndex);
  if (index < 0) {
    index = nativeMax(length + index, 0);
  }
  return baseIndexOf(array, value, index);
}

小结

我们通过了解indexOf方法的实现,同时了解到了其核心方法baseIndexOf的实现,我们也认识到,对于判断NaN的封装如baseIsNaN方法以及严格遍历匹配符合项的strictIndexOf方法等。

除此之外,我们也了解到baseFindIndex内部方法,该方法是查找目标项的索引值,以及了解到对于NaN的索引查找处理baseFindIndex内部方法。