想法来源

因为最近在制作一个抽奖类的 Web 页面,在模拟测试时需要生成随机数,于是就用到了 JavaScript 的Math.random()函数,但是因为需要随机数的范围有限制,便 Google 查找相应的配置方法,在 Stack Overflow 上有人推荐用 Lodash 可以很方便的实现产生定制的随机数。

我才知道原来还有这么方便的一个封装好的库,还是通过原生 JS 实现的。

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

Lodash 内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,其中部分是目前 ECMAScript 尚未制定的规范,但同时被业界所认可的辅助函数。

Lodash _random() 源码分析

Lodash Github :random.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 以下为 Lodash random.js 源码。
// 注释为自己的理解,如有不正确敬请谅解。

const freeParseFloat = parseFloat;

// 函数接受三个参数,
// lower 为随机数范围起始值,
// upper 为随机数范围最大值,
// floating 表示指定是否返回浮点数。
function random(lower, upper, floating) {
// 以下步骤为判断参数的位置。
if (floating === undefined) {
// 判断 upper 或 lower 是否为 Boolean 值
if (typeof upper == 'boolean') {
floating = upper;
upper = undefined;
} else if (typeof lower == 'boolean') {
floating = lower;
lower = undefined;
}
}
// 如果 lower 和 upper 都没有被指定,则默认 lower 为0 ,upper 为1。
if (lower === undefined && upper === undefined) {
lower = 0;
upper = 1;
} else {
// 将 lower 转化为一个有限数字。
// Lodash 的 toFinite() 函数
// 源码地址:https://github.com/lodash/lodash/blob/master/toFinite.js
lower = toFinite(lower);
// 同样,判断参数位置。
if (upper === undefined) {
upper = lower;
lower = 0;
} else {
// 将 upper 转化为一个有限数字。
upper = toFinite(upper);
}
}
// 将 lower 和 upper 排序
if (lower > upper) {
const temp = lower;
lower = upper;
upper = temp;
}
// 判断是否需要生成浮点随机数
if (floating || lower % 1 || upper % 1) {
// 生成浮点随机数(带小数)
// 使用 Math.random() 生成一个范围在[0,1)的浮点,伪随机数。
const rand = Math.random();
// 取 rand 的长度
const randLength = `${rand}`.length - 1;
// 通过 Math.min() 找出两者中最小的值,并返回
// freeParseFloat = parseFloat, 解析字符串(`1e-${randLength}`),并返回浮点数。
return Math.min(
lower +
(rand * (upper - lower + freeParseFloat(`1e-${randLength}`)), upper)
);
}
// 生成非浮点数(整数)的随机数,通过 Math.floor() 向下取整。
return lower + Math.floor(Math.random() * (upper - lower + 1));
}

export default random;

总结

说出来你可能不信,分析了一遍 Lodash 的 Random 函数的实现,真的能学到很多编程思想。

比如怎么样可以使一个函数具有通用性且具有包容性(指在参数不齐全时也能照常执行)。

这是非常值得我学习的地方!

共勉!