方法介绍
lodash中的floor方法的作用跟Math.floor
类似,但是其接受两个参数:_.floor(number,[precision=0])
- number 就是要取舍的值
- precision 就是向下取舍的精度,按官方的解释就是,可以理解为保留几位小数,这也是跟Math.floor有区别的地方
源码讲解
import createRound from './.internal/createRound.js'
/**
*
* floor(4.006)
* // => 4
*
* floor(0.046, 2)
* // => 0.04
*
* floor(4060, -2)
* // => 4000
*/
const floor = createRound('floor')
export default floor
源码中可以看到,其主要的就是一个createRound函数,看下createRound函数内部代码:
/**
* Creates a function like `round`.
*
* @private
* @param {string} methodName The name of the `Math` method to use when rounding.
* @returns {Function} Returns the new round function.
*/
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)
}
}
export default createRound
在createRound函数内部,返回了一个函数,该函数也就是lodash的floor方法的主体了
- func = Math[methodName],我们传入的是floor,所以func就是Math.floor
- precision == null,双等号非严格等于,所以precision可能是undefiend和null,此时,为precision赋值0,在看后面的表达式,就是precision的取值范围在 -292 - 292之间
- 如果precision为0的话,就直接返回 func(number),也就是Math.floor(number) 如果传入了精度值precision,进入到条件判断内部
- 先定义一个数组(let pair =
${number}e
.split('e')),其值为[number,''],不过此时的number类型为字符串了
const number = 4.006;
`${number}e`.split('e') //['4.006','']
- 调用func(Math.floor)方法,
${pair[0]}e${+pair[1] + precision}
就是将number乘以10的precision次方,例如传入的number是4.006,precision是2,'4.006e2',科学计数法,就是4.006*10^2,此时得到的value值就是一个放大了10的precision次方被的整数(例子中就是400)
${pair[0]}e${+pair[1] + precision} //4.006e2 === 400.6
const value = Math.floor(4.006e2) //400
${value}e
.split('e'),又将value同之前的number一样,搞成一个数组赋值给pair,其值是[value,''],value的类型是字符串
pair = `${value}e`.split('e') // '400e'.split('e') == ['400','']
- 最后,return +
${pair[0]}e${+pair[1] - precision}
,字符串模版里面的,就跟上面得到value时的字符串模板一样,不同的是,上面是+precision
,这里是-precision
,也就是,如果上面是乘以10^2,这里就是除以10^2了(乘以10^-2),也就是前面如果放大了,这里就需要缩小了,如果precision
是负数呢,前面是缩小,这里就该放大了,还原number;前面的+就是利用隐式类型转换,将字符串转为数字了
`${pair[0]}e${+pair[1] - precision}` //'400e-2'
+'400e-2' //400e-2 === 4
这里总结个疑问:
- 为什么每次都是将number或则value搞成一个数组,在下次的字符串拼接中在取数组的下标
换成数组再使用下标,或则是直接使用${number}来代替pair[0],是一样的,没有任何区别,应该只是个人写法的问题