lodash源码分析之isIndex

本文为读 lodash 源码的第五十六篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

源码分析

isIndex 的作用是用来判断传入的 value 是否为合法的数组或者类数组索引。

几个常量

/** Used as references for various `Number` constants. */
const MAX_SAFE_INTEGER = 9007199254740991

/** Used to detect unsigned integer values. */
const reIsUint = /^(?:0|[1-9]\d*)$/

MAX_SAFE_INTEGER 是最大安全整数,因为 javascript 使用的是双精度浮点数,能安全表示的最大值为 9007199254740991

reIsUint 用来判断值是否带符号。即是否是 +19-19 这样的形式。

length值判断

isIndex 的整体源码如下:

function isIndex(value, length) {
  const type = typeof value
  length = length == null ? MAX_SAFE_INTEGER : length

  return !!length &&
    (type === 'number' ||
      (type !== 'symbol' && reIsUint.test(value))) &&
        (value > -1 && value % 1 == 0 && value < length)
}

它的第二个参数 length 可以指定合法 index 的范围,如果没有指定的时候,默认的范围为最大安全整数 MAX_SAFE_INTEGER

如果指定的 length 不存在或者为 0,则肯定没有合法的 index 值。

对value的type判断

(type === 'number' ||
      (type !== 'symbol' && reIsUint.test(value)))

可以看到,valuetype 要么是 number 类型,或者 resIsUint.test(value)true 。这句代码很讲究,此时的 value 可以是除了 number 外的其他类型,也即可能是 stringobjectsymbol 等等,用正则的 test 方法,会将 value 隐式转换为 string,再判断是否符合 resIsUint 的正则。这就是为什么要排除 symbol 的原因了,因为规范中规则 symbol 在隐式转换为 stringnumber 时,会抛出 TypeError 错误,具体见参考资料中的 ECMA规范

对value 范围判断

value > -1 && value % 1 == 0 && value < length

value 通过隐藏转换成 number 类型后,要满足三个条件才是合法的 index

  • value > -1
  • value % 1 === 0 ,能被 1 整除,和第一个条件合起来,即表示 value 要为自然数
  • value < length ,即比指定的范围要小

参考资料

ECMA规范

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面

results matching ""

    No results matching ""