携手创作,共同成长!这是我参与「掘金日新计划 · 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,意在转换为指定类型的数据。
通过本篇章,我们也加深了对通用方法封装的思考。