Open giscafer opened 6 years ago
_.castArray、_.ceil、_.chunk、_.clamp
_.castArray
_.ceil
_.chunk
_.clamp
此函数比较简单
/** * 将 `value`转为数组(如果`value`不是数组的话) * @since 4.4.0 * @category Lang * @param {*} value The value to inspect. * @returns {Array} Returns the cast array. * @example * * castArray(1) * // => [1] * * castArray({ 'a': 1 }) * // => [{ 'a': 1 }] * * castArray('abc') * // => ['abc'] * * castArray(null) * // => [null] * * castArray(undefined) * // => [undefined] * * castArray() * // => [] * * const array = [1, 2, 3] * console.log(castArray(array) === array) * // => true */ function castArray(...args) { if (!args.length) { return [] } // 取出第一个参数,判断如果不是数组则转为数组形式 const value = args[0]; return Array.isArray(value) ? value : [value] } export default castArray
/** * Creates a function like `round`. * 创建一个类似 `round` 的函数 * @private * @param {string} methodName 四舍五入时使用的 `Match` 的方法名称。 * @returns {Function} 返回一个新的函数 */ function createRound(methodName) { // 取得 Math 中的函数 const func = Math[methodName]; // 返回一个匿名函数 return (number, precision) => { // 默认为0 和控制最大值为292 precision = precision == null ? 0 : Math.min(precision, 292); // precision!==0 if (precision) { // 用指数符号变换以避免浮点问题 // See [MDN](https://mdn.io/round#Examples) for more details. // 这里`${number}e`加入了e字符,为了下边能直接使用pair[1]取值而不需要判断是否存在 let pair = `${number}e`.split('e'); // 先算出e `precision` 科学计算结果 const value = func(`${pair[0]}e${+pair[1] + precision}`) // 再恢复原来的位数 pair = `${value}e`.split('e') return +`${pair[0]}e${+pair[1] - precision}` } // 没有参数直接Math[methodName](number) return func(number) } } export default createRound
改函数主要功能为 createRound.js
createRound.js
import createRound from './.internal/createRound.js' /** * 根据精度计算精确的数值,向上一位取整,类似Math.ceil(不支持precision参数) * * @since 3.10.0 * @category Math * @param {number} number The number to round up. * @param {number} [precision=0] The precision to round up to. * @returns {number} Returns the rounded up number. * @example * * ceil(4.006) * // => 5 * * ceil(6.004, 2) * // => 6.01 * * ceil(6040, -2) * // => 6100 */ const ceil = createRound('ceil') export default ceil
import slice from './slice.js' /** * Creates an array of elements split into groups the length of `size`. * If `array` can't be split evenly, the final chunk will be the remaining * elements. * 将一个数组拆分为 `size` 长度的数组,如果`array`不能拆分,则最后一个 chunk 将是剩余元素组成。 * * @since 3.0.0 * @category Array * @param {Array} array The array to process. * @param {number} [size=1] The length of each chunk * @returns {Array} Returns the new array of chunks. * @example * * chunk(['a', 'b', 'c', 'd'], 2) * // => [['a', 'b'], ['c', 'd']] * * chunk(['a', 'b', 'c', 'd'], 3) * // => [['a', 'b', 'c'], ['d']] */ function chunk(array, size) { // 避免size为负数情况 size = Math.max(size, 0) const length = array == null ? 0 : array.length if (!length || size < 1) { return [] } let index = 0 let resIndex = 0; // 定义结果数组,长度为 Math.ceil(length / size) const result = new Array(Math.ceil(length / size)) while (index < length) { // 依次 slice 数组 result[resIndex++] = slice(array, index, (index += size)) } return result } export default chunk
/** * Clamps `number` within the inclusive `lower` and `upper` bounds. * 在 `lower` 和 `upper` 两个数值范围界限下,取得合适的 `number` * @since 4.0.0 * @category Number * @param {number} number The number to clamp. * @param {number} lower The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the clamped number. * @example * * clamp(-10, -5, 5) * // => -5 * * clamp(10, -5, 5) * // => 5 */ function clamp(number, lower, upper) { // 都转为数值型 number = +number lower = +lower upper = +upper // 排除lower、upper 为 NaN lower = lower === lower ? lower : 0 upper = upper === upper ? upper : 0 // 排除number 为 NaN if (number === number) { // 取出三个数值中中间值 number = number <= upper ? number : upper number = number >= lower ? number : lower } return number } export default clamp
_.castArray、_.ceil、_.chunk、_.clamp 这几个模块代码都比较简单,都为简单的属性计算和类型判断,对于非数值参数的判断,我们在_.clamp 函数也可以看到先用 + 号转为 number 型,最后再判断是否对于自己本身的方式 来排除了所有非数值型&NaN的情况。同样的判断方式在 _.isNumber 函数里边我们页可以简单。
先用 + 号转为 number 型,最后再判断是否对于自己本身的方式
_.isNumber
源码+测试代码见:lodash-sourcecode-study 前端学堂:felearn.com
内容
_.castArray
、_.ceil
、_.chunk
、_.clamp
源码学习
_.castArray
此函数比较简单
./.internal/createRound.js
_.ceil
改函数主要功能为
createRound.js
_.chunk
_.clamp
总结
_.castArray
、_.ceil
、_.chunk
、_.clamp
这几个模块代码都比较简单,都为简单的属性计算和类型判断,对于非数值参数的判断,我们在_.clamp
函数也可以看到先用 + 号转为 number 型,最后再判断是否对于自己本身的方式
来排除了所有非数值型&NaN的情况。同样的判断方式在_.isNumber
函数里边我们页可以简单。源码+测试代码见:lodash-sourcecode-study 前端学堂:felearn.com