生成任意长度随机字符串
/**
* @param {Number} len
*/
const getRandomStr = (len) => {
let str = "";
while(str.length < len) {
str += Math.random().toString(36).substring(2);
}
return str.substring(0, len);
}
利用了Math.random().toString方法可以接收一个基数作为参数,这个基数从2到36封顶。如果不指定,默认基数是10进制。
PS 随机串长度小于10时,建议在获取后做是否存在校验。
const getRandomStr = (len) => {
let str = "";
while(str.length < len) {
str += Math.random().toString(36).substring(2);
}
return str.substring(0, len);
}
let lArr = [3, 5, 10, 15] // 随机字符串长度
let rArr = [100, 1000, 10000] // 随机次数
let obj = {}; // 记录随机字符串
// 验证随机字符串重复概率
const testRandom = () => {
lArr.forEach( len => {
rArr.forEach( r => {
let total = r, count = 0;
while(r--) {
let rs = getRandomStr(len);
if(obj[rs]) {
count++ ;
} else {
obj[rs] = true;
}
}
console.log(`随机生成${len}位字符串${total}次,重复${count}个,重复率${Math.round(count/total*10000)/100}%。`);
obj = {};
})
})
}
testRandom();
// 随机生成3位字符串100次,重复0个,重复率0%。
// 随机生成3位字符串1000次,重复10个,重复率1%。
// 随机生成3位字符串10000次,重复971个,重复率9.71%。
// 随机生成5位字符串100次,重复0个,重复率0%。
// 随机生成5位字符串1000次,重复0个,重复率0%。
// 随机生成5位字符串10000次,重复1个,重复率0.01%。
// 随机生成10位字符串100次,重复0个,重复率0%。
// 随机生成10位字符串1000次,重复0个,重复率0%。
// 随机生成10位字符串10000次,重复0个,重复率0%。
// 随机生成15位字符串100次,重复0个,重复率0%。
// 随机生成15位字符串1000次,重复0个,重复率0%。
// 随机生成15位字符串10000次,重复0个,重复率0%。
RGB色值转Hex格式
/**
* RGB色值转Hex格式
* @param {String} color 'rgb(255,23,23)' || 'rgba(255,23,23,0.3)'
*/
const colorRGB2Hex = (color) => {
let rgb = color.split(',');
if(rgb.length > 3) {
// rgba(255,255,255,75)
// rgba 格式,a(取值范围0-1)
// 如需要,可特殊处理
}
let r = parseInt(rgb[0].split('(')[1]);
let g = parseInt(rgb[1]);
let b = parseInt(rgb[2].split(')')[0]);
let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
return hex;
}
比较俩个对象是否相等
/**
* 深度比较两个对象是否相同
* @param {Object} oldData
* @param {Object} newData
*/
const isEquals = (oldData, newData) => {
// 类型为基本类型时,如果相同,则返回true
if (oldData === newData) return true;
if (isObject(oldData) && isObject(newData) && Object.keys(oldData).length === Object.keys(newData).length) {
// 类型为对象并且元素个数相同
// 遍历所有对象中所有属性,判断元素是否相同
for (const key in oldData) {
if (oldData.hasOwnProperty(key)) {
if (!isEquals(oldData[key], newData[key]))
// 对象中具有不相同属性 返回false
return false;
}
}
} else if (isArray(oldData) && isArray(oldData) && oldData.length === newData.length) {
// 类型为数组并且数组长度相同
for (let i = 0, length = oldData.length; i < length; i++) {
if (!isEquals(oldData[i], newData[i]))
// 如果数组元素中具有不相同元素,返回false
return false;
}
} else {
// 其它类型,均返回false
return false;
}
// 走到这里,说明数组或者对象中所有元素都相同,返回true
return true;
};
dom元素是否可见
/**
* 判断元素是否可见
* @param {Object} el
*/
export const checkVisible = (el) => {
let rect = el.getBoundingClientRect();
//获取当前浏览器的视口高度,不包括工具栏和滚动条
//document.documentElement.clientHeight兼容 Internet Explorer 8、7、6、5
let viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
//bottom top是相对于视口的左上角位置
//bottom大于0或者top-视口高度小于0可见
return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}
字节转换
/**
* parsma {Number} bytes
* params {Boolean} returnArr 某些特殊情况需要数值与单位分开处理
*/
const bytesToSize = (bytes, returnArr) => {
if (bytes == 0) return returnArr ? ['0', 'B'] : '0B';
if (bytes > 0 && bytes < 1) return returnArr ? [bytes, 'B'] : bytes + 'B';
let base = 1024, // or 1024
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(base));
// if (i > 4) i = 4; //此处可设置截取最大单位
bytes = roundToTwo(bytes / Math.pow(base, i)) //保留小数点后俩位
return returnArr ? [bytes, sizes[i]] : bytes + sizes[i];
}
保留2位小数
const roundToTwo = (decimal) => {
return +(Math.round(Number(decimal + "e+2")) + "e-2");
};
判断类型
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
}
getType({}); //'Object'
getType([]); //'Array'
getType("a"); //'String'
getType(1); //'Number'
getType(function () {}); //'Function'
getType(true); //'Boolean'
getType(null); //'Null'
getType(undefined); //'Undefined'
少位补零
//ES5方法:
var zeroize = function (value, length) {
if (!length) { length = 2; }
value = String(value);
for (i = 0,zeros = ''; i < (length - value.length); i++) {
zeros += "0";
}
return zeros + value;
};
zeroize(9); //retunrn "09"
//ES6方法:
var zeroize = function (value, length) {
if (!length) { length = 2; }
value = String(value);
return value.padStart(length,'0');
};
zeroize(9); //retunrn "09"
百分比计算
//保留俩位小数
function getPercentage(num,total){
var num = num&&typeof num == "number"&&num || 0;
var total = total&&typeof total == "number"&&total || 0;
return Math.round(num/total*10000)/100 + '%'
}
数字每3位加','
方法众多,转换成数组处理、正则表达式等,此处仅举例一种转换成字符串后处理
function toThoussands(num) {
var num = (num || 0).toString(),result = '';
while(num.length > 3) {
result = ',' + num.slice(-3) + result;
num = num.slice(0,num.length - 3);
}
if(num) {
result = num + result;
}
return result;
}
Date数据格式化
function FormatTimeDate(){
Date.prototype.Format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
};
}
数组去重
- ES6:
[...new Set([1,2,3,1,'a',1,'a'])]
//...是扩展运算符
- ES5:
[1,2,3,1,'a',1,'a'].filter(function(v,i,array){
return i === array.indexOf(v);
})
var result = [];
var obj = {};
[1,2,3,1,'a',1,'a'].forEach(function(v){
if(!obj[typeof v + v + '']){
obj[typeof v + v + ''] = true;
result.push(v);
}
});
return result;
PS.上中使用obj[typeof v + v + ''] ,是因为对象的key值为被转换为字符串,obj[1] == obj['1'],所以用"type + value"来判断去重。
根据条件过滤数组
/**
* filterArr 过滤数组
* @param {Array} data [需要过滤的原始数组]
* @param {Object} filterObj [过滤条件,这里写成key-value键值对]
* @parsm {String} type [过滤条件之间的关系,&& or ||]
*/
function filterArr(data, filterObj, type) {
let filters = Object.keys(filterObj);
return data.filter((item) => {
let flag = filters.reduce((t, v, i) => {
if (t === 'first' && i === 0) {
//第一次执行时
return item[v].includes(filterObj[v]);
} else if (type === 'or') {
//过滤条件之间为||关系,满足一个即可
return t || item[v].includes(filterObj[v]);
} else if (type === 'and') {
//过滤条件之间为&&关系,满足全部
return t && item[v].includes(filterObj[v]);
}
}, 'first');
/**
* Array.reduce方法,在不传初始值的情况下,length为1是不执行的,大坑!!!
* Array.reduce方法,接受俩个参数:Array.reduce((pre, cur, index, array)=>{ ...}, [initValue]);
* pre (上一次调用返回的值,或者是提供的初始值(initValue))
* cur (数组中当前被处理的元素)
* index (当前元素在数组中的索引)
* array (调用reduce的数组)
* initValue (作为第一次调用的第一个参数)
*
* reduce方法,如果不传initialValue,在数组length为1的时候,JS引擎是不执行的。。。。所以在数据长度不确定的情况下,一定要记得传initialValue
*/
return flag;
})
}
根据path删除Obj的Key
var delObjectKey = function(obj, path) {
try {
if ((typeof(obj) === 'object' || typeof(obj) === 'array') && path) {
let pathArray = path.split('.');
let get_value = function(obj, pathArray) {
let key = pathArray.shift();
if (key != 'undefined' && key.length < 5 && parseInt(key)) {
key = parseInt(key);
}
if (!obj[key]) {
return false;
}
if (pathArray.length == 0) {
return delete obj[key];
}
obj = obj[key];
return get_value(obj, pathArray);
}
return get_value(obj, pathArray);
}
return false;
} catch (error) {
console.log(error);
}
}