资讯专栏INFORMATION COLUMN

我来阅读lodash源码——Math(一)

levinit / 1723人阅读

摘要:首先是通过创建一个函数,然后向其传递参与计算的值,也就是说应该是返回一个函数,并且有两个参数。事实上就是这样,返回值是一个,是被加数,是加数。

源码注释版

这一组函数都是数学计算相关的,主要分为三类:

加减乘除:addsubtractmultiplydivide

求最大最小平均值:maxmaxByminminBysumsumBymeanmeanBy

小数的四舍五入:ceilfloorround

加减乘除

在加减乘除的源码中可以看到这四个函数都引用了一个 createMathOpeartion 这个函数,然后是这样使用这个函数的:

// 加法
const add = createMathOperation((augend, addend) => augend + addend, 0)
// 减法
const subtract = createMathOperation((minuend, subtrahend) => minuend - subtrahend, 0)
// 乘法
const multiply = createMathOperation((multiplier, multiplicand) => multiplier * multiplicand, 1)
// 除法
const divide = createMathOperation((dividend, divisor) => dividend / divisor, 1)

可以发现,它们的实现方式都是一样的,向 createMathOperation 传递一个函数,这个函数就是原生的加减乘除,所以主要的还是要看看 createMathOperation 是啥。

createMathOperation

源码注释版

/**
 * Creates a function that performs a mathematical operation on two values.
 *
 * @private
 * @param {Function} operator The function to perform the operation.
 * @param {number} [defaultValue] The value used for `undefined` arguments.
 * @returns {Function} Returns the new mathematical operation function.
 */

从这个函数说明中可以看出,这个函数有两个参数:

operator:原生四则运算函数

defaultValue:默认值,当未传递参数时返回的(原生计算中一般返回 NaN

我们拿 add 来举例。

const add = createMathOperation((augend, addend) => augend + addend, 0)
const result = add(5, 3)
console.log(result) // 8

首先是通过 createMathOperation 创建一个 add 函数,然后向其传递参与计算的值,也就是说 createMathOperation 应该是返回一个函数,并且有两个参数。事实上就是这样,返回值是一个 function(value, other)value 是被加数,other 是加数。

在进行加减乘除运算的时候,还需要考虑一点的就是参与计算的两个值的数据类型,是字符串还是数字?或者是 undefined?这里的实现方法满足以下几个规则:

两个值都为 undefined 时,返回 defaultValue

其中一个值为 undefined 时,返回另一个值

有一个值为字符串时,用 baseToString 将两个值都转换成 string 进行计算

其它情况,用 baseToNumber 将两个值都转换成 number 进行计算

undefined 和 null 在四则运算中的区别

我注意到代码中是判断 value === undefined,是 ===,说明这里严格区分 undefinednull ,这是之前没注意到的地方。这是为什么呢?

我拿原生的加减乘除做了个实验:

console.log(1 + undefined) // NaN
console.log(1 + null) // 1
console.log(1 - undefined) // NaN
console.log(1 - null) // 1
console.log(1 * undefined) // NaN
console.log(1 * null) // 0
console.log(1 / undefined) // NaN
console.log(1 / null) // Infinity

undefined 参与计算的结果都是 NaNnull 参与计算是将它看作 0

嗯,我们不一样,每个人都有不同的境遇 ~

But,why?为啥我们不一样?

我们知道 undefinednull 其中有一个区别是:

undefined 是定义了但是没有赋值

null 是为定义

如果按照这个区别,应该把 undefined 当作 0 啊,但是结果貌似不是这样,查查规范咯

在这就看得比较清楚了,ToNumber 运算符会将 undefined 转换成 NaN,而将 null 转换成 +0

baseToString

源码注释版

/**
 * The base implementation of `toString` which doesn"t convert nullish
 * values to empty strings.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 */

规则:

如果 typeof 返回 string,则直接返回 value

如果是数组,则递归对数组中的每一项都执行 baseToString,直到不是数组为止,返回的是一个不含 [] 的字符串,相当于 [].join("") 的结果

如果 isSymbol 判断为 true,则用 toString.call 来转换

其它情况,就直接用模板字符串的方式返回字符串

对于 isSymbol,感觉还没理解到位,先不展开说了。。。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90035.html

相关文章

  • Lodash源码讲解-chunk函数

    摘要:原文首发于源码讲解这是我们阅读源码的第篇博客,在这篇文章里我们来学习一下的方法。好啦,关于函数暂时就先讲到这里啦。与恶龙缠斗过久自身亦成为恶龙凝视深渊过久深渊将回以凝视。 原文首发于Lodash源码讲解 这是我们阅读Lodash源码的第2篇博客,在这篇文章里我们来学习一下Lodash的chunk方法。 chunk函数内部依赖其他的函数,依赖的函数如下所示; slice 按照惯例,我们先...

    ISherry 评论0 收藏0
  • 聊聊lodash的debounce实现

    摘要:同时,这里会设置一个定时器,在等待后会执行,的主要作用就是触发。最后,如果不再有函数调用,就会在定时器结束时执行。问题就出在对于定时器的控制上。 本文同步自我的Blog 前段时间团队内部搞了一个代码训练营,大家组织在一起实现 lodash 的 throttle 和 debounce,实现起来觉得并不麻烦,但是最后和官方的一对比,发现功能的实现上还是有差距的,为了寻找我的问题,把官方源码...

    junfeng777 评论0 收藏0
  • lodash源码分析之chunk的尺与刀

    摘要:万条数据依赖读源码之从看稀疏数组与密集数组原理的原理归结起来就是切割和放置。尺在切割之前,需要用尺确定切割的数量。容器的长度刚好与块的数量一致。当与块的数量相等时,表示已经切割完毕,停止切割,最后将结果返回。 以不正义开始的事情,必须用罪恶使它巩固。——莎士比亚《麦克白》 最近很多事似乎印证了这句话,一句谎言最后要用一百句谎言来圆谎。 本文为读 lodash 源码的第二篇,后续文章会...

    ZweiZhao 评论0 收藏0
  • 30秒就能理解的 Javascript 代码片段 --- Array篇

    摘要:而这个秒就能理解的代码片段,摒弃了许多不必要的代码,只实现了最核心的部分,不像和那样,考虑参数边界值问题,例如,参数的类型是否符合预期等。使用根据断言函数对数组进行过滤,返回条件为真值的对象。 之前翻译过一篇文章,《我喜欢的5个编程技巧》,里面的一个技巧是借鉴一个网站的代码片段,好奇的小手点下链接后,发现是一个有 47000 多star的仓库,30-seconds-of-code。 仓...

    fox_soyoung 评论0 收藏0
  • 「读懂源码系列2」我从 lodash 源码中学到的几个知识点

    摘要:今天要讲的,是我从的源码实现文件中学到的几个很基础,却又容易被忽略的知识点。在函数式编程中,函数是一等公民,它可以只是根据参数,做简单的组合操作,再作为别的函数的返回值。所以,阅读源码,是一种很棒的重温基础知识的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面试题系列8」数组去重(1...

    Amio 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<