大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
今天给大家带来的主题是前端的一个随机数开源库,即 Aimless.js,相信大家在日常工作中都有机会使用它。话不多说,直接开始!
1.什么是 Aimless.js
在大型游戏引擎和框架之外,很少支持在 JavaScript 中生成随机数。 当然,原生 Math.random 函数有很多替代品,但如果想生成一个指定范围内的随机数怎么办?特别是,如果想生成的结果不是 0 到 1 之间的数字怎么办?
在这种情况下,Aimless.js 诞生了,它补全了 JS 在随机数方面的空白,而且体积很小 (< 6kB)、相对独立、无任何外部依赖,并提供各种有用的随机数实用程序。 比如:用于生成随机数、从数组中选取随机元素、获取指定范围内的随机数等等。 最重要的是,Aimless.js 可以与开发者最喜欢的 PRNG(伪随机数生成器)集成,为应用程序提供额外的随机层。
值得注意的是,Aimless.js 依赖于 ES5 数组方法,并在所有现代浏览器中得到支持,但是 Aimless.js 未计划支持旧版或已弃用的浏览器。
2.使用 Aimless.js
基础使用
首先需要安装 Aimless.js 并将其添加到 package.json 依赖项中。
$ npm install aimless.js --save
然后将函数导入到将使用它们的文件中。
import { bool, intRange } from "aimless.js";
使用自定义 PRNG
Aimless.js 与任何返回数字 num >= 0 和 num < 1 的自定义 PRNG 兼容,每个函数都接受一个要使用的 engine。
import { bool } from "aimless.js";
const engine = () => 0;
bool(engine); // false
此外,Aimless 中的每个函数都有一个名为 withEngine 的对应函数。这个函数将返回它的对应部分,并在引擎周围有一个闭包,所以开发者不需要每次都传递它。
import { boolWithEngine } from "aimless.js";
const engine = () => 0;
const bool = boolWithEngine(engine);
bool(); // false
如果没有提供自定义引擎,每个函数都将默认使用提供的 defaultEngine。默认引擎在宿主环境支持时使用 crypto.getrandomvalues 方法,并在环境不支持时候回退到 Math.random 方法。
3.Aimless.js 常见 API 介绍
bool(engine)
返回 true 或 false。
char(string, engine)
从提供的字符串中返回一个随机字符。
const randomChar = char("the missing JS randomness library");
// 可能返回 's', ' ', 'l', etc
customDist(function, engine)
按照选择的自定义分布返回一个随机数,函数应接受 0 到 1 之间的数字。
const randomOfCustomDist = customDist((randomNumber) => randomNumber / 2);
exponentialDist(lambda, engine)
使用提供的 lambda 返回一个服从指数分布的随机数。
const samples = [];
const lambda = 0.5;
for (let i = 0; i < 100000; i++) {
const randomValue = exponentialDist(lambda);
samples.push(randomValue);
}
// 可以预期 `samples` 的平均值为 (1 / lambda) +/- 0.01,
// 生成更多样本将确保 (1 / lambda) 的均值
floatRange(min, max, engine)
返回 min 和 max 之间的随机浮点数。
const randomFloat = floatRange(0.1, 0.2);
intRange(min, max, engine)
返回 min 和 max 之间的随机整数。
const randomInteger = intRange(5, 10);
intSequence(min, max, engine)
以随机顺序返回一个数组,其中包含 min 和 max 之间的所有整数。
const intSeq = intSequence(-1, 3);
// 返回 [3,-1,2,1,0], [0,2,-1,3,1], etc
normalDist(mean, stdDev, engine)
返回一个服从均值 mean 和标准差 stdDev 的正态分布的随机数。
const samples = [];
for (let i = 0; i < 100000; i++) {
const randomValue = normalDist(0, 1);
samples.push(randomValue);
}
// 可以期望 `samples` 的平均值为 0 +/- 0.01,
// 生成更多样本将确保平均值为 0
oneOf(array, engine)
从提供的数组中返回一个随机项。
const randomItem = oneOf([1, 2, 3]);
const randomObj = oneOf([{ a: 1 }, { b: 2 }, { c: 3 }]);
seedFunc(seed)
返回一个种子随机数生成器,种子 RNG 产生随机数,但如果使用相同的种子,则结果可以预测。注意:Park-Miller PRNG 用于提供种子功能,因此不接受 engine。
const seededFunction = seedFunc(1);
seededFunction(); // 0.000007825903601782307
seededFunction(); // 0.13153778773875702
seededFunction(); // 0.7556053220812281
const newSeeded = seedFunc(1);
newSeeded(); // 0.000007825903601782307
newSeeded(); // 0.13153778773875702
newSeeded(); // 0.7556053220812281
sequence(array, engine)
返回一个新数组,其中包含数组中包含的相同项目,但顺序是随机的。
const randomSeq = sequence([1, 2, 3]);
// 可能返回 [3,1,2], [2,3,1], etc.
uniqFuncIntRange(min, max, engine)
使用提供的引擎返回 min 和 max 之间的唯一随机数。如果没有传递 engine,将使用 defaultEngine,如果没有剩余的唯一值可返回,则返回 null。
const uniqueRNG = uniqFuncIntRange(1, 3);
uniqueRNG(); // 2
uniqueRNG(); // 3
uniqueRNG(); // 1
uniqueRNG(); // null
uniqFuncSequence(array, engine)
使用提供的 engine 从提供的数组中返回一个唯一的随机数。如果没有传递 engine 参数,将使用 defaultEngine。如果没有剩余的唯一值可返回,则返回 null。
const uniqueRNG = uniqFuncSequence([10, 20, 30]);
uniqueRNG(); // 20
uniqueRNG(); // 30
uniqueRNG(); // 10
uniqueRNG(); // null
uuid(engine)
使用提供的 engine 返回有效的 RFC4122 版本 4 ID 十六进制字符串。
const id = uuid();
console.log(id); // ef486db4-7f49-43b3-a1ea-b0e0a22bc944
weighted(numbers, weights, engine)
返回提供的 numbers 之一,偏向于提供的相应权重,数字可以包括浮点数。
const weightedDiceRoll = weighted([1, 2, 3, 4, 5, 6], [1, 1, 1, 1, 1, 10]);
// 将比其他选项更频繁地返回 6
4.其他随机数方案
当然,除了 Aimless.js 外,一些其他的开源随机数方案也值得大家重点关注,比如:
seedrandom.js
用于 JavaScript 的种子随机数生成器,可用作纯 JS 脚本、Node.js 或 AMD 模块。在Github上通过MIT协议开源,有1.9k的star、项目依赖量达到了 187k。
// 本地 PRNG:不影响 Math.random。
var seedrandom = require('seedrandom');
var rng = seedrandom('hello.');
console.log(rng());
// 返回 0.9282578795792454
// 全局 PRNG: set Math.random.
seedrandom('hello.', { global: true });
console.log(Math.random());
// 始终返回 0.9282578795792454
Chance.js
Chance.js是JavaScript 的随机生成器助手,可以生成随机数、字符、字符串、名称、地址和几乎任何其他东西。在 Github 上通过 MIT 协议开源,有 6.2k 的star、项目依赖量达到了 76.1k,代码贡献者100+,是一个非常优秀的前端开源项目。
Random.js
即一个数学上正确的 JavaScript 随机数生成器库,灵感主要来自 C++11 的 <random>。目前在Github上通过MIT协议开源,有0.6k的star、值得长期关注。
// ES6 模块
import { Random } from "random-js";
const random = new Random();
// uses the nativeMath engine
const value = random.integer(1, 100);
5.本文总结
本文主要和大家介绍下前端的一个非常强大的随机数开源库,即 Aimless.js。相信通过本文的阅读,大家对 Aimless.js 都会有一个初步的了解。
因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!
参考资料
https://github.com/ChrisCavs/aimless.js
https://chriscavs.github.io/aimless-demo/
https://www.cssscript.com/random-number-generator-aimless/
https://github.com/davidbau/seedrandom
https://github.com/ckknight/random-js
https://chancejs.com/
https://github.com/chancejs/chancejs
https://dev.to/chriscavs/aimlessjs-the-missing-js-randomness-library-29k3