Lodash 加减乘除 add、subtract、multiply、divide方法源码解读

我们先看下Lodash中文文档对add方法的解释:

_.add(augend, addend)
两个数相加。
参数
augend (number): 相加的第一个数。
addend (number): 相加的第二个数。
返回
(number): 返回总和。
例子

_.add(6, 4);
// => 10

接下来 我们通过源码层次来看看add方法的具体用法

const add = createMathOperation((augend, addend) => augend + addend, 0)

export default add

从源码层次可以看出 add方法是createMathOperation方法返回的函数,createMathOperation方法传入两个参数:
第一个参数是一个普通的add逻辑方法
第二个参数是一个默认值0

function createMathOperation(operator, defaultValue) {
  //返回一个函数 value,other是调用lodash方法(例如_add)传入的参数
  return (value, other) => {
    //如果第一个参数和第二个参数都没有定义 则返回默认值0
    if (value === undefined && other === undefined) {
      return defaultValue
    }
    //如果第一个参数有值 第二个参数没有值 则返回第一个参数
    if (value !== undefined && other === undefined) {
      return value
    }
    //如果第一个参数没有值 第二个参数有值 则返回第二个参数
    if (other !== undefined && value === undefined) {
      return other
    }
    //如果第一个参数或者第二个参数为字符串(至少其中一个为字符串) 则将参数通过baseToString方法都转换为字符串
    if (typeof value === 'string' || typeof other === 'string') {
      value = baseToString(value)
      other = baseToString(other)
    }
    else {
      //如果两个参数都不是字符串  则将参数通过baseToNumber方法都转换为数字
      value = baseToNumber(value)
      other = baseToNumber(other)
    }
    //这个时候将被转换的参数传入createMathOperation方法的第一个操作函数,并返回结果
    return operator(value, other)
  }
}

代码里的baseToString方法

function baseToString(value) {
  // 如果是字符串 直接返回
  if (typeof value === 'string') {
    return value
  }
  // 如果是数组 递归转换值(易受调用堆栈限制的影响)
  if (Array.isArray(value)) {
    return `${value.map(baseToString)}`
  }
  //如果是Symbol值  调用 Symbol.prototype.toString.call方法进行转换 例如:Symbol('a') 的转换结果为 'Symbol(a)'
  if (isSymbol(value)) {
    return symbolToString ? symbolToString.call(value) : ''
  }
  //对字符串0 返回0 或者'-0'的处理 这块我还没有想到什么应用场景 欢迎补充
  const result = `${value}`
  return (result === '0' && (1 / value) === -INFINITY) ? '-0' : result
}

代码里的baseToNumber方法

function baseToNumber(value) {
  //如果是数字 直接返回
  if (typeof value === 'number') {
    return value
  }
  //如果是Symbol类型  返回NAN
  if (isSymbol(value)) {
    return NAN
  }
  //将字符串通过+转换为数字
  return +value
}

baseToString,baseToNumber方法中的isSymbol方法

function isSymbol(value) {
  const type = typeof value
  return type == 'symbol' || (type === 'object' && value != null && getTag(value) == '[object Symbol]')
}

通过源码我们发现

——add()     // 0 没有传参数直接返回默认值0
_add(true)  //  true  只有第一个参数 返回 
_add(undefined,'5') // '5' 只有第二个参数直接返回
_add(3,5)     //返回 8
_add('3',5)   // 返回 '35'
_add('3',['5',4])  //返回 '35,4' 数组相加先调Array.prototype.toString方法 ['5',4]转为'5,4'
_add('3',Symbol('a'))  //返回 '3Symbol(a)'

Lodash中 subtract方法(减法)、multiply方法(乘法)、divide方法(除法)都是通过createMathOperation实现的

subtract方法

 * subtract(6, 4)
 * // => 2
 */
const subtract = createMathOperation((minuend, subtrahend) => minuend - subtrahend, 0)

export default subtract

multiply方法

 * multiply(6, 4)
 * // => 24
 */
const multiply = createMathOperation((multiplier, multiplicand) => multiplier * multiplicand, 1)

export default multiply

divide方法

 * divide(6, 4)
 * // => 1.5
 */
const divide = createMathOperation((dividend, divisor) => dividend / divisor, 1)

export default divide
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值