最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Lodash 源码解读(一)

    正文概述 掘金(炽翎)   2021-05-03   560

    前言

    近期比较提升一下自己的代码功底,看到知乎有关注的大佬每天分析一个 npm 包的源码,想到自己的项目里用到 Lodash 的地方比较多,于是决定阅读一下 Lodash 的源码,看一看这种大型的开源工具函数库有哪些细节值得学习。

    .internal

    addMapEntry

    /**
     * 向 map 中添加键值对
     *
     * @private
     * @param {Object} map 需要修改的 map
     * @param {Array} pair 需要添加至 map 中的键值对
     * @returns {Object} 返回修改后的 map
     */
    function addMapEntry(map, pair) {
      // 不能返回 map.set 因为它在 IE 11 中是不能被链式调用的
      map.set(pair[0], pair[1]);
      return map;
    }
    
    export default addMapEntry;
    

    addSetEntry

    /**
     * 向 set 中添加值
     *
     * @private
     * @param {Object} set 需要修改的 set
     * @param {*} value 需要添加至 set 中的值
     * @returns {Object} 返回修改后的 set
     */
    function addSetEntry(set, value) {
      // 不能返回 set.add 因为它在 IE 11 中是不能被链式调用的
      set.add(value);
      return set;
    }
    
    export default addSetEntry;
    

    arrayEach

    /**
     * 数组 forEach 函数的专用版本
     *
     * @private
     * @param {Array} [array] 需要遍历的数组
     * @param {Function} iteratee 每次迭代调用的函数
     * @returns {Array} 返回遍历后的数组
     */
    function arrayEach(array, iteratee) {
      let index = -1;
      const length = array.length;
    
      while (++index < length) {
        // 迭代调用的函数返回 false 时跳出
        if (iteratee(array[index], index, array) === false) {
          break;
        }
      }
      return array;
    }
    
    export default arrayEach;
    

    arrayEachRight

    /**
     * 数组 forEachRight 函数的专用版本
     *
     * @private
     * @param {Array} [array] 需要遍历的数组
     * @param {Function} iteratee 每次迭代调用的函数
     * @returns {Array} 返回遍历后的数组
     */
    function arrayEachRight(array, iteratee) {
      let length = array == null ? 0 : array.length;
    
      while (length--) {
        // 迭代调用的函数返回 false 时跳出
        if (iteratee(array[length], length, array) === false) {
          break;
        }
      }
      return array;
    }
    
    export default arrayEachRight;
    

    arrayIncludes

    import baseIndexOf from './baseIndexOf.js';
    
    /**
     * 数组 includes 的特殊版本
     * 不支持指定索引
     *
     * @private
     * @param {Array} [array] 需要查找的数组
     * @param {*} target 需要搜索的值
     * @returns {boolean} 如果 target 被找到则返回 true 否则返回 false
     */
    function arrayIncludes(array, value) {
      // 利用了 JavaScript 在 == 时会自动进行类型转换的特性
      // 过滤了 undefined 和 null
      const length = array == null ? 0 : array.length;
      // 利用了 JavaScript 在 ! 时会自动进行类型转换的特性
      // 将 length 由 number 转换为 boolean
      return !!length && baseIndexOf(array, value, 0) > -1;
    }
    
    export default arrayIncludes;
    

    这个函数引入了 baseIndexOf 函数,所以这个函数的实现也需要了解一下。

    import baseFindIndex from './baseFindIndex.js';
    import baseIsNaN from './baseIsNaN.js';
    import strictIndexOf from './strictIndexOf.js';
    
    /**
     * indexOf 的基本实现
     * 不支持 fromIndex 的边界检查
     *
     * @private
     * @param {Array} array 需要查找的数组
     * @param {*} value 需要搜索的值
     * @param {number} fromIndex 查找起始索引
     * @returns {number} 如果查找到匹配的值则返回其索引 否则返回 -1
     */
    function baseIndexOf(array, value, fromIndex) {
      // 利用了 JavaScript 的 NaN 不等于 NaN 本身的特性
      // 区分了 NaN 与非 NaN
      return value === value
        ? strictIndexOf(array, value, fromIndex)
        : baseFindIndex(array, baseIsNaN, fromIndex);
    }
    
    export default baseIndexOf;
    

    同样,baseIndexOf 函数引入了 baseFindIndexbaseIsNaNstrictIndexOf 函数,所以这些函数的实现也需要了解一下。

    /**
     * indexOf 的特殊版本
     * 会对值进行严格相等比较 即 ===
     *
     * @private
     * @param {Array} array 需要查找的数组
     * @param {*} value 需要搜索的值
     * @param {number} fromIndex 查找起始索引
     * @returns {number} 如果查找到匹配的值则返回其索引 否则返回 -1
     */
    function strictIndexOf(array, value, fromIndex) {
      let index = fromIndex - 1;
      const {length} = array;
    
      while (++index < length) {
        if (array[index] === value) {
          return index;
        }
      }
      return -1;
    }
    
    export default strictIndexOf;
    
    /**
     * isNaN 的基本实现
     * 不支持 Number 对象
     *
     * @private
     * @param {*} value 需要判断的值
     * @returns {boolean} 如果值为 NaN 则返回 true 否则返回 false
     */
    function baseIsNaN(value) {
      // 利用了 JavaScript 的 NaN 不等于 NaN 本身的特性
      // 区分了 NaN 与非 NaN
      return value !== value;
    }
    
    export default baseIsNaN;
    
    /**
     * findIndex 和 findLastIndex 的基本实现
     *
     * @private
     * @param {Array} array 需要查找的数组
     * @param {Function} predicate 每次迭代调用的函数
     * @param {number} fromIndex 查找起始索引
     * @param {boolean} [fromRight] 指定查找方向从右向左
     * @returns {number} 如果查找到匹配的值则返回其索引 否则返回 -1
     */
    function baseFindIndex(array, predicate, fromIndex, fromRight) {
      const {length} = array;
      let index = fromIndex + (fromRight ? 1 : -1);
    
      while (fromRight ? index-- : ++index < length) {
        if (predicate(array[index], index, array)) {
          return index;
        }
      }
      return -1;
    }
    
    export default baseFindIndex;
    

    起源地下载网 » Lodash 源码解读(一)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元