javascript - 跪求大神解答关于lodash中dropWhile方法源码的疑惑

查看:131
本文介绍了javascript - 跪求大神解答关于lodash中dropWhile方法源码的疑惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

dropWhile/dropRightWhile 中第二个参数 支持Function,String,Object, 文档也有说当传入不同类型的时候,会用相应的方法处理,但是我看源码,没看到这个是在哪里做处理的,以dropWhile为例:

dropWhile.js

import baseWhile from './.internal/baseWhile.js';
function dropWhile(array, predicate) {
  return (array && array.length)
    ? baseWhile(array, predicate, true)
    : [];
}
export default dropWhile;

baseWhile.js

import baseSlice from './baseSlice.js';
function baseWhile(array, predicate, isDrop, fromRight) {
  const length = array.length;
  let index = fromRight ? length : -1;

  while ((fromRight ? index-- : ++index < length) &&
    predicate(array[index], index, array)) {} 

  return isDrop
    ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
    : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
}

export default baseWhile;

baseSlice.js

function baseSlice(array, start, end) {
  let index = -1,
      length = array.length

  if (start < 0) {
    start = -start > length ? 0 : (length + start)
  }
  end = end > length ? length : end
  if (end < 0) {
    end += length
  }
  length = start > end ? 0 : ((end - start) >>> 0)
  start >>>= 0

  const result = Array(length)
  while (++index < length) {
    result[index] = array[index + start]
  }
  return result
}

export default baseSlice

从这几个部分的源代码上看,并没有对第二个参数(predicate)进行任何的判断和处理就直接在baseWhile.js 进行运用,如果出入是String或Object类型的怎么去调用文档所说的_.matches
_.matchesProperty_.property方法?

  while ((fromRight ? index-- : ++index < length) &&
    predicate(array[index], index, array)) {} 

这个地方十分的不解,求大神解答,感谢!

解决方案

predicate 应该是有处理的,因为即使传入的不是一个 function,也没有报错,如果不是对 predicate 进行了处理,那就肯定对异常进行了处理,这个好好找找

while 这句不能单独看,要结合上一句

let index = fromRight ? length : -1;

while ((fromRight ? index-- : ++index < length) &&
    predicate(array[index], index, array)) {} 

合起来看就是,如果 fromRight,就从最大的 index 开始,依次 index--,直到 index === 0,这时候 index 会判 false,循环结果。

如果不是 fromRight 就从 0 到 length(不含) 循环。因为是 ++index,先加再判断,所以 index 要初始化为 -1 才会从 0 开始。为什么要 ++index 呢,是因为后面 predicate 要用到 index,这个时候不管 ++index 还是 index++,都已经加过了。如果 index 从 0 开始,用 index++,后 predicate 里的第一个 index 就是 1,但期望是从 0 开始。

补充

lodash 源码,在 Github 上找到的和 CDN 上找到的有点不一样。CDN 的在这里:https://cdnjs.cloudflare.com/...

摘抄 dropWhile 的源码,

// drop while
function dropWhile(array, predicate) {
  return (array && array.length)
    ? baseWhile(array, getIteratee(predicate, 3), true)
    : [];
}

可以看到,用 getIteratee(predicate, 3)predicate 进行了处理。

function getIteratee() {
  var result = lodash.iteratee || iteratee;
  result = result === iteratee ? baseIteratee : result;
  return arguments.length ? result(arguments[0], arguments[1]) : result;
}

getIteratee() 里面调用了 iteratee 这个全局函数

function iteratee(func) {
  return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
}

iteratee 判断如果参数不是函数,调用 baseClone,这个就有点复杂了,在 2641 行(如果用 VSCode 可以用 [F12] 跳转过去,其它编辑器不清楚有没类似功能)

这篇关于javascript - 跪求大神解答关于lodash中dropWhile方法源码的疑惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆