lodash里的subtract和multiply

419 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

使用说明

subtract

在lodash里,subtract方法是两数相减操作,同时该方法接收两个数字类型的参数。

_.subtract(6, 4);
// => 2

_.subtract()
// => 0

_.subtract(2)
// => 2

_.subtract(2,'1')
// => 1

_.subtract([],'3')
// => -3

_.subtract(()=>{},'3')
// => NaN

对于非正常的参数,subtract方法都能够将其转成默认的数字类型再进行减法的数字操作。

multiply

_.multiply(2,3)
// => 6

_.multiply('3',3)
// => 9

_.multiply()
// => 1

_.multiply(3)
// => 3

_.multiply('3',[])
// => 0

_.multiply([],[])
// => 0

_.multiply(1,()=>{})
// => NaN

对于非正常的参数,multiply方法同样能够将其转成默认的数字类型再进行乘法的数字操作。

实现

我们同样能够根据现象模拟内部实现,在实现上对接收的参数进行严谨性判断:

function subtract(num1, num2) {
    if (num1 === undefined && num2 === undefined) return 0
    if (num1 !== undefined && num2 === undefined) return num1
    if (num2 !== undefined && num1 === undefined) return num2
    return num1 - num2
}

function multiply(num1, num2) {
    if (num1 === undefined && num2 === undefined) return 0
    if (num1 !== undefined && num2 === undefined) return num1
    if (num2 !== undefined && num1 === undefined) return num2
    return num1 * num2
}

源码

在两个方法的实现上,由于重复的判断逻辑,我们可以进行封装抽离。

在之前的篇章中,我们也讲到了工厂函数的实现,该工厂函数正是lodash内部封装的供数字操作创建调用的。

function createMathOperation(operator, defaultValue) {
  return (value, other) => {
    if (value === undefined && other === undefined) {
      return defaultValue
    }
    if (value !== undefined && other === undefined) {
      return value
    }
    if (other !== undefined && value === undefined) {
      return other
    }
    if (typeof value === 'string' || typeof other === 'string') {
      value = baseToString(value)
      other = baseToString(other)
    }
    else {
      value = baseToNumber(value)
      other = baseToNumber(other)
    }
    return operator(value, other)
  }
}

export default createMathOperation

createMathOperation工厂函数通过传入操作方法以及默认值,默认值是传参错误时返回值,而操作方法在内部只负责调用。

lodash里的数字操作方法:

  • add方法里的+操作。
  • divide方法里的/操作。
  • subtract方法里的-操作。
  • multiply方法里的*操作。

所以回归到源码实现上,subtract方法实现只需进行如下调用:

const subtract = createMathOperation((minuend, subtrahend) => minuend - subtrahend, 0)

同理,multiply方法源码实现如下:

const multiply = createMathOperation((multiplier, multiplicand) => multiplier * multiplicand, 1)

回顾add方法和divide方法的实现,其源码也是也是调用该方法。

add方法源码实现:

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

divide方法源码实现:

const divide = createMathOperation((dividend, divisor) => dividend / divisor, 1)

小结

结合前面几个篇章,我们了解到lodash源码里,对于数字操作,如add、divide、subtract、multiply,均是调用同一个工厂函数createMathOperation,该工厂函数是数字操作共同逻辑处理的方法抽离,主要是进行严谨性判断。

同时在工厂函数里调用了封装了的工具方法baseToString和baseToNumber,意在转换为指定类型的数据。

通过本篇章,我们也加深了对通用方法封装的思考。