文章目录
数组相关
/**
* 数组排序
* @param {*} arr
* @param {*} type 1: 升序 2: 降序 3: 随机
* @returns 会改变原数组,返回排序后的数组
*/
function sort(arr, type = 1) {
if(!(arr instanceof Array)) throw new Error('The argument is not an Array.')
return arr.sort((a, b) => {
switch (type) {
case 1:
return a - b;
case 2:
return b - a;
case 3:
return Math.random() - 0.5;
default:
return arr;
}
})
}
/**
* 数组去重
* @param {*} arr
* @returns 返回新数组,不改变原数组, 浅拷贝:对新数组深层数据进行操作会影响原数组
*/
function unique(arr) {
if(!(arr instanceof Array)) throw new Error('The argument is not an Array.')
return [...new Set(arr)]
}
/**
* 求 n 个集合的并集
* @param {*} argvs Array
* @returns 返回新数组,不改变原数组, 浅拷贝:对新数组深层数据进行操作会影响原数组
*/
function union(...argvs) {
argvs.forEach(x => {
if(!(x instanceof Array)) throw new Error('The argument is not an Array.')
})
var newArr = []
argvs.forEach(x => {
newArr = newArr.concat(x)
})
return [...new Set(newArr)]
}
console.log(union([1,2,3], [4, 5, 6], [1, 3, 6])) // [ 1, 2, 3, 4, 5, 6 ]
/**
* 遍历多维数组 深度优先
* @param {*} arr
* @param {*} callback 回调函数
*/
function each(arr, callback) {
if(!(arr instanceof Array)) throw new Error('参数必须为数组')
arr.forEach((item, index, arr) => {
if (item instanceof Array) {
each(item, callback)
}
callback(item, index, arr)
})
}
var arr = [1, [2, 3, [4, 5, 6, [7, 8, 9, 10]]]]
each(arr, (x, i, a) => {
console.log(x, i, a)
})
/**
* 多维数组扁平化
* @param {*} arr
* @returns
*/
function flatten(arr) {
return arr.toString().split(',')
}
字符串相关
/**
* 字符串去重
* @param {*} str 要去重的字符串
* @return 返回处理后的字符串
*/
function unique(str) {
return str.replace(/(\w)\1+/g, '$1')
}
/**
* 去除空白字符串
* @param {*} str
* @param {*} type 1-所有空格 2-前后空格 3-前空格 4-后空格
* @returns
*/
function trim(str, type = 1) {
switch (type) {
case 1:
return str.replace(/\s+/g, "");
case 2:
return str.replace(/(^\s*)|(\s*$)/g, "");
case 3:
return str.replace(/(^\s*)/g, "");
case 4:
return str.replace(/(\s*$)/g, "");
default:
return str;
}
}
/**
* 大小写转换
* @param {*} str
* @param {*} type 1:首字母大写 2:首字母小写 3:大小写转换 4:全部大写 5:全部小写
* @returns
*/
function changeCase(str, type = 5) {
switch (type) {
case 1:
return str.replace(/\b\w+\b/g, function (word) {
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
});
case 2:
return str.replace(/\b\w+\b/g, function (word) {
return word.substring(0, 1).toLowerCase() + word.substring(1).toUpperCase();
});
case 3:
return str.split('').map(function (word) {
if (/[a-z]/.test(word)) {
return word.toUpperCase();
} else {
return word.toLowerCase()
}
}).join('')
case 4:
return str.toUpperCase();
case 5:
return str.toLowerCase();
default:
return str;
}
}
// 去除html标签
removeHtmltag: (str) => {
return str.replace(/<[^>]+>/g, '')
}
判断数据类型
/**
* 输入一个值,返回其数据类型
* @param {*} para 要判断数据类型的值
* @return 返回类型 eg: "[object String]"
*/
function type(para) {
return Object.prototype.toString.call(para)
}
将数据组织成树状结构
具体请参考----根据id和parentId将数据组织成树状结构
/**
* 根据id将数据组织成树状结构
* @param ary 要组织的数据
* @param pid 最顶层数据的id值
* @param pidName 父id字段名
* @returns {*}
*/
function formatToTree(ary, pid, pidName = 'parentId') {
return ary
.filter((item) => item[pidName] === pid)
.map((item) => {
// 通过父节点ID查询所有子节点
item.children = formatToTree(ary, item.id);
return item;
});
}
// 用法
formatToTree(data, 1)
对象深拷贝
/**
* 深拷贝 Object 或 Array
* @param {*} obj
* @param {*} parent
* @returns
*/
function deepClone(obj, parent = null){
let result; // 最后的返回结果
let _parent = parent; // 防止循环引用
while(_parent){
if(_parent.originalParent === obj){
return _parent.currentParent;
}
_parent = _parent.parent;
}
if(obj && typeof obj === "object"){ // 返回引用数据类型(null已被判断条件排除))
if(obj instanceof RegExp){ // RegExp类型
result = new RegExp(obj.source, obj.flags)
}else if(obj instanceof Date){ // Date类型
result = new Date(obj.getTime());
}else{
if(obj instanceof Array){ // Array类型
result = []
}else{ // Object类型,继承原型链
let proto = Object.getPrototypeOf(obj);
result = Object.create(proto);
}
for(let key in obj){ // Array类型 与 Object类型 的深拷贝
if(obj.hasOwnProperty(key)){
if(obj[key] && typeof obj[key] === "object"){
result[key] = deepClone(obj[key],{
originalParent: obj,
currentParent: result,
parent: parent
});
}else{
result[key] = obj[key];
}
}
}
}
}else{ // 返回基本数据类型与Function类型,因为Function不需要深拷贝
return obj
}
return result;
}
生成随机数范围 [min, max]
/**
* 生成随机数范围 [min, max]
* @param {*} min 最小值
* @param {*} max 最大值
* @param {*} type 是否生成小数点,默认false
* @returns
*/
function ramdon(min, max, type = false) {
if(typeof min !== 'number' || typeof max !== 'number') {
min = parseFloat(min)
max = parseFloat(max)
}
if(min == max) return min
if(min > max) [min, max] = [max, min]
if (!type) {
return Math.floor(min + Math.random() * ((max + 1) - min))
} else {
let num = min + Math.random() * ((max + 1) - min)
if (num > max || num < min) {
num = ramdon(min, max, type)
}
return num
}
}
格式化时间
/**
* 格式化时间
* @param {String | Date | Number} date 日期
* @param {String} format 时间格式 例:YYYY-MM-DD HH:mm:ss
* @returns 处理后的时间字符串
*/
function dateFormat(date = new Date(), format = 'YYYY-MM-DD HH:mm:ss') {
var date = new Date(date);
var year = date.getFullYear(); // 年
var month = date.getMonth() + 1; // 月
var day = date.getDate(); // 日
var hour = date.getHours(); // 时
var min = date.getMinutes(); // 分
var sec = date.getSeconds(); // 秒
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
hour = hour < 10 ? "0" + hour : hour;
min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
format = format.replace(/(YYYY)+/i, year)
format = format.replace(/(MM)+/, month)
format = format.replace(/(DD)+/i, day)
format = format.replace(/(HH)+/i, hour)
format = format.replace(/(mm)+/, min)
format = format.replace(/(ss)+/i, sec)
return format
}
防抖与节流
/**
* 函数防抖
* @param {Function} func 防抖函数
* @param {Number} wait 延迟执行毫秒数
* @param {Boolean} immediate true 表立即执行,false 表延迟执行
* @returns
*/
function debounce(func, wait = 500, immediate = false) {
let timeout;
return function() {
let context = this; // 保存 this 指针
let args = arguments; // 保存 arguments
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
} else {
timeout = setTimeout(()=>{
func.apply(context, args)
}, wait);
}
}
}
/**
* 函数节流
* @param {Function} func 节流函数
* @param {Number} wait 延迟执行毫秒数
* @returns
*/
function throttle(func, wait = 500) {
let previous = 0;
return function() {
let context = this;
let now = Date.now();
if (now - previous > wait) {
func.apply(context, arguments);
previous = now;
}
}
}
导出Excel表格
导出json数据为Excel表格
具体使用方式参考----javascript将JSON数据导出为Excel表格
/**
* 导出json数据为Excle
* @param {json} data 要导出的json数据
* @param {String} head 表头 例:'名字,邮箱,电话'
* @param {*} name 导出的文件名, 可选
*/
function jsonToExcel(data, head, name = '导出的文件名') {
// 1、拼接 json 数据
let str = head ? head + '\n' : '';
data.forEach(item => {
for(let key in item) {
// 添加 \t 是为了防止表格出现科学计数法等其他格式
str = `${str + item[key] + '\t'},`
}
str += '\n' // 换行
});
console.log(str)
// 2、encodeURIComponent解决中文乱码
const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
// 3、通过创建a标签实现
const link = document.createElement("a");
link.href = uri;
// 4、对下载的文件命名
link.download = `${name + '.csv'}`;
link.click();
}
直接通过html数据导出Excel表格
具体使用方式参考----javascript将JSON数据导出为Excel表格
/**
* 直接导出html表格数据为Excle
* @param {*} selector 表格元素选择器
* @param {*} name 导出的文件名
*/
function jsonToExcel(selector, name = '导出的文件名') {
// 1、获得表格数据的html标签和文本d;
var html = "<html><head><meta charset='UTF-8'></head><body>"+document.querySelector(selector).outerHTML+"</body></html>";
// 2、创建一个Blob对象,第一个参数是文件的数据,第二个参数是文件类型属性对象
var blob = new Blob([html],{type:"application/vnd.ms-excel"});
// 3、通过创建a标签实现下载
const link = document.createElement("a");
// 4、利用URL的createObjectURL方法为 a 元素生成 blobURL
link.href = URL.createObjectURL(blob);
// 5、设置文件名
link.download = `${name}`;
link.click();
}
文字消息转为语音播放
/**
* 文字消息转为语音播放
* @param {String} textToSpeak 要播放的文字消息
*/
function speak(textToSpeak) {
window.speechSynthesis.cancel();
const newUtterance = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices()
newUtterance.text = textToSpeak.replace(/\[|\]/g, '');
const CN = voices.filter(item => item.lang === 'zh-CN')
const localCN = CN.filter(item => item.localService)
newUtterance.voice = localCN.length?localCN[0]:CN[0]
window.speechSynthesis.speak(newUtterance);
}
cookie管理
const cookie = {
/**
* 设置cookie
* @param {String} name 名
* @param {*} value 值
* @param {Number} time cookie有效期
* @returns
*/
set: function (name, value, time) {
document.cookie = name + '=' + value + '; max-age=' + time;
return this;
},
/**
* 删除cookie
* @param {String} name 名
* @returns
*/
remove: function (name) {
return this.set(name, '', -1);
},
/**
* 获取cookie
* @param {String} name
* @returns
*/
get: function (name, callback) {
var allCookieArr = document.cookie.split('; ');
for (var i = 0; i < allCookieArr.length; i++) {
var itemCookieArr = allCookieArr[i].split('=');
if (itemCookieArr[0] === name) {
return itemCookieArr[1]
}
}
return undefined;
}
}
sessionStorage 管理
const session = {
// 数据存储到本地缓存
set: (key, value, day) => {
let d = new Date();
let time = 0;
day = (typeof (day) === 'undefined' || !day) ? 1 : day;// 时间,默认存储1天
time = d.setHours(d.getHours() + (24 * day));// 毫秒
window.sessionStorage.setItem(key, JSON.stringify({ value, time }));
},
// 获取本地缓存数据
get: (key) => {
let obj = window.sessionStorage.getItem(key);
if (obj && obj !== undefined && obj !== null) {
let data = JSON.parse(obj);
if (new Date().getTime() > data.time) { // 过期
sessionStorage.removeItem(key);
return null;
} else {
return data.value;
}
}
return '';
},
// 清除本地缓存数据
remove: (key) => {
if (key) {
// 删除键为name的缓存
window.sessionStorage.removeItem(key);
} else {
// 清空全部
window.sessionStorage.clear();
}
},
seek: (name) => {
if (!name) return;
return window.sessionStorage.hasOwnProperty(name);
},
};
localStorage 管理
const local = {
/**
* 设置localStorage
* @param key 键名
* @param value 键值
* @param expires 有效时长, 单位毫秒, 默认7天
*/
setItem: (key, value, expires = 7 * 24 * 60 * 60 * 1000) => {
const d = new Date();
expires = d.setTime(d.getTime() + expires);
window.localStorage.setItem(key, JSON.stringify({value, expires}));
},
/**
* 获取localStorage
* @param key 键名
* @returns {*}
*/
getItem: (key) => {
const obj = window.localStorage.getItem(key);
try {
const data = JSON.parse(obj);
if(Date.now() > data.expires) {
window.localStorage.removeItem(key)
return null;
} else {
return data.value;
}
} catch(err) {
return null
}
},
/**
* 删除localstorage
* @param key 键名
*/
removeItem: (key) => {
if (key) {
window.localStorage.removeItem(key);
}
},
/**
* 清楚localstorage
*/
clear: () => {
window.localStorage.clear();
},
/**
* 判断是否有值
* @param key 键名
* @returns {boolean}
*/
seek: (key) => {
if (!key) return false;
return window.localStorage.hasOwnProperty(key);
},
};
将数字金额转换为大写金额
/**
* 将数字金额转换为大写金额
* @param {*} Num
* @returns
*/
function changeToChinese(Num) {
//判断如果传递进来的不是字符的话转换为字符
if (typeof Num == "number") {
Num = new String(Num);
};
Num = Num.replace(/,/g, "") //替换tomoney()中的“,”
Num = Num.replace(/ /g, "") //替换tomoney()中的空格
Num = Num.replace(/¥/g, "") //替换掉可能出现的¥字符
if (isNaN(Num)) { //验证输入的字符是否为数字
//alert("请检查小写金额是否正确");
return "";
};
//字符处理完毕后开始转换,采用前后两部分分别转换
var part = String(Num).split(".");
var newchar = "";
//小数点前进行转化
for (var i = part[0].length - 1; i >= 0; i--) {
if (part[0].length > 10) {
return "";
//若数量超过拾亿单位,提示
}
var tmpnewchar = ""
var perchar = part[0].charAt(i);
switch (perchar) {
case "0":
tmpnewchar = "零" + tmpnewchar;
break;
case "1":
tmpnewchar = "壹" + tmpnewchar;
break;
case "2":
tmpnewchar = "贰" + tmpnewchar;
break;
case "3":
tmpnewchar = "叁" + tmpnewchar;
break;
case "4":
tmpnewchar = "肆" + tmpnewchar;
break;
case "5":
tmpnewchar = "伍" + tmpnewchar;
break;
case "6":
tmpnewchar = "陆" + tmpnewchar;
break;
case "7":
tmpnewchar = "柒" + tmpnewchar;
break;
case "8":
tmpnewchar = "捌" + tmpnewchar;
break;
case "9":
tmpnewchar = "玖" + tmpnewchar;
break;
}
switch (part[0].length - i - 1) {
case 0:
tmpnewchar = tmpnewchar + "元";
break;
case 1:
if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
break;
case 2:
if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
break;
case 3:
if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
break;
case 4:
tmpnewchar = tmpnewchar + "万";
break;
case 5:
if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
break;
case 6:
if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
break;
case 7:
if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
break;
case 8:
tmpnewchar = tmpnewchar + "亿";
break;
case 9:
tmpnewchar = tmpnewchar + "拾";
break;
}
var newchar = tmpnewchar + newchar;
}
//小数点之后进行转化
if (Num.indexOf(".") != -1) {
if (part[1].length > 2) {
// alert("小数点之后只能保留两位,系统将自动截断");
part[1] = part[1].substr(0, 2)
}
for (i = 0; i < part[1].length; i++) {
tmpnewchar = ""
perchar = part[1].charAt(i)
switch (perchar) {
case "0":
tmpnewchar = "零" + tmpnewchar;
break;
case "1":
tmpnewchar = "壹" + tmpnewchar;
break;
case "2":
tmpnewchar = "贰" + tmpnewchar;
break;
case "3":
tmpnewchar = "叁" + tmpnewchar;
break;
case "4":
tmpnewchar = "肆" + tmpnewchar;
break;
case "5":
tmpnewchar = "伍" + tmpnewchar;
break;
case "6":
tmpnewchar = "陆" + tmpnewchar;
break;
case "7":
tmpnewchar = "柒" + tmpnewchar;
break;
case "8":
tmpnewchar = "捌" + tmpnewchar;
break;
case "9":
tmpnewchar = "玖" + tmpnewchar;
break;
}
if (i == 0) tmpnewchar = tmpnewchar + "角";
if (i == 1) tmpnewchar = tmpnewchar + "分";
newchar = newchar + tmpnewchar;
}
}
//替换所有无用汉字
while (newchar.search("零零") != -1)
newchar = newchar.replace("零零", "零");
newchar = newchar.replace("零亿", "亿");
newchar = newchar.replace("亿万", "亿");
newchar = newchar.replace("零万", "万");
newchar = newchar.replace("零元", "元");
newchar = newchar.replace("零角", "");
newchar = newchar.replace("零分", "");
if (newchar.charAt(newchar.length - 1) == "元") {
newchar = newchar + "整"
}
return newchar;
}
将阿拉伯数字转换成大写中文
/**
* 将阿拉伯数字翻译成中文的大写数字
* @param {*} num
* @returns
*/
export const numberToChinese = (num) => {
const Number = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾");
const Unit = new Array("", "十", "百", "仟", "萬", "億", "点", "");
// 分开小数和整数部分
const a = ("" + num).replace(/(^0*)/g, "").split(".");
// 关键节点单位判断
let k = 0;
// 最终转化的字符
let result = "";
// 整数部分处理
for (let i = a[0].length - 1; i >= 0; i--) {
switch (k) {
case 0:
result = Unit[7] + result;
break;
case 4:
if (!new RegExp("0{4}//d{" + (a[0].length - i - 1) + "}$").test(a[0])) {
result = Unit[4] + result;
}
break;
case 8:
result = Unit[5] + result;
Unit[7] = Unit[5];
k = 0;
break;
}
if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) {
result = Number[0] + result;
}
if (a[0].charAt(i) != 0) {
result = Number[(a[0].charAt(i)) % 10] + Unit[k % 4] + result;
}
k++;
}
// 加上小数部分(如果有小数部分)
if (a.length > 1) {
result += Unit[6];
for (let i = 0; i < a[1].length; i++) {
result += Number[a[1].charAt(i)];
}
}
if (result == '壹十') {
result = "十";
}
if (result.match(/^壹/) && result.length == 3) {
result = result.replace("壹", "");
}
return result;
};