携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
方法说明
floor
floor方法主要是根据第二个参数(精度)向下舍入 ,为其保留一定数量的小数位。
其中,方法的第一个参数和第二个参数均为数字类型,返回值也是数字类型。
_.floor(4.006);
// => 4
_.floor(0.046, 2);
// => 0.04
_.floor(4060, -2);
// => 4000
_.floor()
// => NaN
_.floor(10.4,3)
// => 10.4
round
round方法主要是根据精度向下舍入,第一个参数为要向下舍入的值,第二个参数为精度。参数类型以及返回值类型均是数字类型。
_.round()
// => NaN
_.floor(4.006);
// => 4
_.floor(0.046, 2);
// => 0.04
_.floor(4060, -2);
// => 4000
_.round([],1)
// => 0
_.round([],2)
// => 0
_.round([],[])
// => 0
对于floor和round,我们均可以通过Math身上的方法处理,而lodash便是在原生方法上进行增强,主要处理参数异常的情况。
源码实现
对于数字操作,由于需要借助Math身上的方法去处理,所以lodash依旧通过一个名为createRound的工厂函数创建,通过传入方法名去获取Math身上相应的方法。
// lodash身上floor方法的实现
const floor = createRound('floor')
// lodash身上round方法的实现
const round = createRound('round')
在ceil方法实现里,我们知道对于大数需要特殊处理的,因为科学计算法的数字带了e参数,在这里,floor方法和round方法 的内部实现对于大数的处理,均和ceil方法的处理是一样的,并且控制精度范围在292位。
所以,对于通用冗余的处理逻辑,lodash对其进行封装、抽离在createRound工厂函数里。
在lodash源码里,createRound则在.internal/createRound.js中导出。
function createRound(methodName) {
const func = Math[methodName]
return (number, precision) => {
precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
if (precision) {
let pair = `${number}e`.split('e')
const value = func(`${pair[0]}e${+pair[1] + precision}`)
pair = `${value}e`.split('e')
return +`${pair[0]}e${+pair[1] - precision}`
}
return func(number)
}
}
可见在lodash源码里,floor的实现是通过转字符串再分割处理,最后调用原生Math.floor方法,而round 最终还是调用Math.round 上的方法。
小结
lodash的floor方法是对原生Math.floor的拓展,round方法也是在原生Math.round上进行拓展 ,二者均是增加了对于精度的控制。
createRound工厂函数是对通用的逻辑处理进行抽离、封装。
实际上在lodash源码里,createRound工厂函数用在三个地方,便是上一篇章里讲解到的ceil,以及本篇章讲到的floor和round。
createRound工厂函数在转换上比较巧妙,所以可通过学习其方法,延伸到大数的运算操作上。