源码注释版

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

  • 加减乘除: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?这里的实现方法满足以下几个规则:

  1. 两个值都为 undefined 时,返回 defaultValue
  2. 其中一个值为 undefined 时,返回另一个值
  3. 有一个值为字符串时,用 baseToString 将两个值都转换成 string 进行计算
  4. 其它情况,用 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.*/

规则:

  1. 如果 typeof 返回 string,则直接返回 value
  2. 如果是数组,则递归对数组中的每一项都执行 baseToString,直到不是数组为止,返回的是一个不含 [] 的字符串,相当于 [].join('') 的结果
  3. 如果 isSymbol 判断为 true,则用 toString.call 来转换
  4. 其它情况,就直接用模板字符串的方式返回字符串

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

我来阅读lodash源码——Math(一)相关推荐

  1. 惰性求值——lodash源码解读

    前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...

  2. 读Lodash源码——chunk.js

    The time is out of joint: O cursed spite, That ever I was born to set it right. --莎士比亚 最艰难的第一步 最近学习遇 ...

  3. lodash源码分析之获取数据类型

    所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...

  4. 学习 lodash 源码整体架构,打造属于自己的函数式编程类库

    前言 这是 学习源码整体架构系列第三篇.整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现.文章学习的是打包整合后的代码,不是实际仓库中 ...

  5. 每天一个Lodash源码解析

    每天一个Lodash源码解析 chunk() 方法介绍 自我实现 源码分析 代码对比 知识点补充 浮点数转化为浮点数 数组创建方法区别 js中切割数组方法 slice() 方法介绍 自我实现 源码分析 ...

  6. lodash源码中debounce函数分析

    lodash源码中debounce函数分析 一.使用 在lodash中我们可以使用debounce函数来进行防抖和截流,之前我并未仔细注意过,但是不可思议的是,lodash中的防抖节流函数是一个函数两 ...

  7. 逐行阅读redux源码(二)combineReducers

    前情提要 逐行阅读redux源码(一)createStore 认识reducers 在我们开始学习源码之前,我们不妨先来看看何谓reducers: 如图所见,我们可以明白, reducer 是用来对初 ...

  8. C++Primer Plus (第六版)阅读笔记 + 源码分析【目录汇总】

    C++Primer Plus (第六版)阅读笔记 + 源码分析[第一章:预备知识] C++Primer Plus (第六版)阅读笔记 + 源码分析[第二章:开始学习C++] C++Primer Plu ...

  9. webuploader 怎么在react中_另辟蹊径搭建阅读React源码调试环境支持所有React版本细分文件断点调试...

    引言(为什么写这篇文章) 若要高效阅读和理解React源码,搭建调试环境是必不可少的一步.而常规方法:使用react.development.js和react-dom.development.js调试 ...

最新文章

  1. c++ 读文件_C语言处理文件基础知识:文件、流和键盘输入
  2. 微软更新Linux子系统,编译WSL 2内核只需3步
  3. python路径怎么找windows_如何查看 windows 中 Python安装路径
  4. 什么是CouchDB?
  5. c 服务器二次验证码,V5验证官网 - 基础套餐免费 -滑块验证,行为验证,防刷验证 - 文档...
  6. re.DOTALL --编写多行模式的正则表达式
  7. 最大的矩形(ccf)
  8. Hibernate异常之关键字错误
  9. 四川大学2012年数学分析考研试题
  10. dababase 差异
  11. Redis 阶段总结
  12. 处女座的砝码 数学结论题
  13. 9700usb网卡 linux驱动,0fe6:9700 usb网卡,终于编译成功驱动。
  14. CC2530看门狗定时器实现1秒定时
  15. 【哪些年,我们一起追的女孩】第五章
  16. python做t检验_Python实现--假设检验:T检验
  17. 非接触借记贷记流程报文解析
  18. 计算到达18岁生日所经过的总天数
  19. python实现四种基本图形的面积计算 :圆形,长方形,正方形,梯形。
  20. 地球上20张最惊人的照片_地球上30个惊人的自然景点

热门文章

  1. vmware workstation 安装esx 启动vt功能
  2. Android中Activity共享变量的另一方法:Application context
  3. IT运维包括最基本的三个方面
  4. php微信菜单40017错误,微信公众号接口添加菜单时错误(errcodequot;:40017 invalid button type) - 好库文摘...
  5. python sched_python事件调度库sched
  6. python类_python类和对象
  7. 十进制转换成十六进制c语言 链栈,C语言 链栈 实现十进制转换二进制,八进制,十六进制...
  8. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)
  9. CDN网络究竟是怎么加速的?
  10. 单片机开发项目全局变量太多怎么管理?