在网上看了很多人用 js 随机数和时间戳生成 id 的方法,我验证过并不可靠,重复的几率很大,所以手写了下面的函数,这个函数生成的id是不会重复的,因为已经做了重复判断。
console.log(Date.now());
function createUniqueId(n) {
var random = function() { // 生成10-12位不等的字符串
return Number(Math.random().toString().substr(2)).toString(36); // 转换成十六进制
}
var arr = [];
function createId() {
var num = random();
var _bool = false;
arr.forEach(v => {
if(v === num) _bool = true;
});
if(_bool) {
createId();
}else {
arr.push(num);
}
}
var i = 0;
while(i < n) {
createId();
i++;
}
return arr;
}
console.log(Date.now());
// 关于random函数,还有其它版本
// 版本一:
var random = function() { // 生成10-12位不等的字符串
return Math.random().toString(36).slice(2); // 截取小数点后的字符串
}
// 版本二:
var random = function(n) { // 生成6位长度的字符串
return (~~(Math.random() * (1 << 30))).toString(36); // "<<"操作相当于乘上2的n次方,"~~"相当于parseInt
}
// 版本三:
var random = function(n) { // 生成n位长度的字符串
if(n === 1) return (~~(Math.random() * 36)).toString(36);
return (~~(Math.random() * 36)).toString(36) + random(n-1); // 递归在性能上不怎么理想,不推荐
}
// 或
var random = function(n) { // 生成n位长度的字符串
return function(n, s) {
if(n === 1) return s;
return random(n -1, (~~(Math.random() * 36)).toString(36) + s);
}(n, (~~(Math.random() * 36)).toString(36));
}
// 版本四:
var random = function(n) { // 生成n位长度的字符串
var str = "abcdefghijklmnopqrstuvwxyz0123456789"; // 可以作为常量放到random外面
var result = "";
for(var i = 0; i < n; i++) {
result += str[parseInt(Math.random() * str.length)];
}
return result;
}
对于前端来说,做数据可视化的时候往往需要唯一的 id 来标识数据。
但是这个函数不适合于后端,因为后端数据库往往会存储亿级的数据量,这时候可以考虑md5之类的方案,例如pgsql
把正整数作id也不错。