原文地址:实用篇:JS工具函数,提高生产力的利器,助力高效开发(一)
在这篇文章中,我们将探讨JavaScript中的工具函数。这些函数是用来解决日常开发中常见问题的实用代码。它们可以极大地提高开发效率和代码质量。
在JavaScript开发过程中,我们经常遇到一些通用的任务,比如处理数组、对象、日期、字符串等。如果每次遇到这些问题,我们都从头开始编写代码,那么开发效率会大大降低。工具函数就是用来解决这些常见问题的。它们提供了一种重用代码的方式,让我们能够更快地完成任务,同时保持代码的清晰和可维护。当然,我们我们也可以使用第三方库,比如lodash是一个非常流行的JavaScript工具库,它提供了许多实用的工具函数。
1、使用正则表达式和replace函数
const numFormat = (num) => {
const str = num.toString();
const res = str.replace(/\d+/, function(n) {
// 先提取整数部分
return n.replace(/(\d)(?=(\d{3})+$)/g, function($1) {
return $1 + ",";
});
})
return res;
}
console.log(numFormat(1649966)) // 1,649,966
console.log(numFormat(673439.6328)); // 673,439.6328
console.log(numFormat(12345.36)) // 12,345.36
2、除法+求模
const numFormat = (num) => {
let n = num;
let r = '';
let temp = '';
do {
// 求模的值, 用于获取高三位,这里可能有小数
mod = n % 1000;
// 值是不是大于1,是继续的条件
n = n / 1000;
// 高三位
temp = ~~mod;
// 1.填充: n > 1 循环未结束, 就要填充为比如 1 => 001
// 不然temp = ~~mod的时候, 1 001, 就会变成 "11"
// 2.拼接“,”
r = (n >= 1 ? `${temp}`.padStart(3, '0') : temp) + (!!r ? ',' + r : '');
} while (n >= 1);
const strNumber = num + '';
let index = strNumber.indexOf('.');
// 拼接小数部分
if (index >= 0) {
r += strNumber.substring(index);
}
return r;
}
console.log(numFormat(1649966)) // 1,649,966
console.log(numFormat(673439.6328)); // 673,439.6328
console.log(numFormat(12345.36)) // 12,345.36
3、数组分割法
const numFormat = (num) => {
// 转为字符串,并按照.拆分
const arr = (num + '').split('.');
// 整数部分再拆分
const int = arr[0].split('');
// 小数部分
const fraction = arr[1] || '';
// 返回的变量
let r = '';
int.reverse().forEach(function (v, i) {
// 非第一位并且是位值是3的倍数,添加“,”
if (i !== 0 && i % 3 === 0) {
r = v + ',' + r;
} else {
// 正常添加字符(这是好写法)
r = v + r;
}
});
// 整数部分和小数部分拼接
return r + (!!fraction ? '.' + fraction : '');
}
console.log(numFormat(1649966)) // 1,649,966
console.log(numFormat(673439.6328)); // 673,439.6328
console.log(numFormat(12345.36)) // 12,345.36
const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const fistLetterUpper = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
console.log(fistLetterUpper('hello word'))
const everyLetterUpper = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
console.log(everyLetterUpper('hello world! today is a wonderful day'));
// Hello World! Today Is A Wonderful Day
// pid代表它的父结点
const list =[
{ id: 1,name:"部门1", pid: 0 },
{ id: 2, name:"部门2", pid:1 },
{ id: 3,name:"部门3", pid: 1 },
{ id: 4,name:"部门4", pid: 3 },
{ id: 5,name:"部门5", pid: 4 }
]
//希望输出的结果
const resultList = [
{
id: 1,
name: "部门1",
pid: 0,
children: [
{
id: 2,
name: "部门2",
pid: 1,
children: []
},
{
id: 3,
name: "部门3",
pid: 1,
children: [
// ...
]
}
]
}
]
1、Map对象实现
const listToTree = (list) => {
//最终树形结构的结果
const result = [];
const itemMap = {};
for (const item of list) {
const id = item.id;
const pid = item.pid;
if (!itemMap[id]) {
itemMap[id] = {
children: [],
}
}
itemMap[id] = {
...item,
children: itemMap[id]["children"]
}
const treeItem = itemMap[id];
if (pid === 0) {
result.push(treeItem);
} else {
if (!itemMap[pid]) {
itemMap[pid] = {
children: [],
}
}
itemMap[pid].children.push(treeItem);
}
}
return result;
}
listToTree(list);
2、递归实现
//递归查找获取子节点
// List扁平数组
// 树形结构最终数据
// 父节点
const childGet = (list, result, pid) => {
for (const item of list) {
if (item.pid === pid) {
const newItem = { ...item, children: [] };
result.push(newItem);
childGet(list, newItem.children, item.id);
}
}
}
// 调用实现
const listToTree = (list, pid) => {
const result = [];
childGet(list, result, pid);
return result;
};
listToTree(list, 0);
3、filter+递归(方法2进阶版)
const listToTree = (list, id, pid='pid') => {
const items = list.filter(item => item[pid] === id);
const result = items.map(item => ({
...item,
children: listToTree(list, item.id)
}));
return result;
}
listToTree(list, 0, 'pid')
const omit = (object, props = []) => {
let res = {};
Object.keys(object).forEach(key => {
if (props.includes(key) === false) {
res[key] = typeof object[key] === 'object' && object[key] !== null ?
JSON.parse(JSON.stringify(object[key])) :
object[key]
}
})
return res;
}
const obj = {
id: '1',
name: '张三',
age: 18,
desc: ''
}
omit(obj, ['age'])
// {id: '1', name: '张三', desc: ''}
const trimFn = (value) => { const str = value.toString(); const reExtraSpace = /^\s*(.*?)\s+$/; return str.replace(reExtraSpace, "$1"); } trimFn(' 12345678 ') // 12345678
const formatDate = (format='Y-M-D h:m:s', timestamp=Date.now()) => {
let date = new Date(timestamp)
let dateInfo = {
Y: date.getFullYear(),
M: date.getMonth()+1,
D: date.getDate(),
h: date.getHours(),
m: date.getMinutes(),
s: date.getSeconds()
}
let formatNumber = (n) => n > 10 ? n : '0' + n
let res = format
.replace('Y', dateInfo.Y)
.replace('M', dateInfo.M)
.replace('D', dateInfo.D)
.replace('h', formatNumber(dateInfo.h))
.replace('m', formatNumber(dateInfo.m))
.replace('s', formatNumber(dateInfo.s))
return res
}
formatDate()
// 2023-11-25 14:26:36
formatDate('Y年M月D日 h时m分s秒')
// 2023年11月25日 14时26分37秒
formatDate('h:m Y-M-D', 1700919198000)
// 21:33 2023-11-25
/**
* @param {function} func - 执行函数
* @param {number} wait - 等待时间
* @param {boolean} immediate - 是否立即执行
* @return {function}
*/
const debounce = (func, wait = 300, immediate = false) => {
let timer, ctx;
let later = (arg) => setTimeout(()=>{
func.apply(ctx, arg)
timer = ctx = null
}, wait)
return function(...arg){
if(!timer){
timer = later(arg)
ctx = this
if(immediate){
func.apply(ctx, arg)
}
}else{
clearTimeout(timer)
timer = later(arg)
}
}
}
let scrollHandler = debounce(function(e){
console.log(e)
}, 500)
window.onscroll = scrollHandler
/**
* @param {function} func - 执行函数
* @param {number} delay - 延迟时间
* @return {function}
*/
const throttle = (func, delay) => {
let timer = null
return function(...arg){
if(!timer){
timer = setTimeout(()=>{
func.apply(this, arg)
timer = null
}, delay)
}
}
}
let scrollHandler = throttle(function(e){
console.log(e)
}, 500)
window.onscroll = scrollHandler
/**
* @param {string} filename - 下载时的文件名
* @param {string} data - base64字符串
*/
const downloadFile = (filename, data) => {
let downloadLink = document.createElement('a');
if (downloadLink) {
document.body.appendChild(downloadLink);
downloadLink.style = 'display: none';
downloadLink.download = filename;
downloadLink.href = data;
if (document.createEvent) {
let downloadEvt = document.createEvent('MouseEvents');
downloadEvt.initEvent('click', true, false);
downloadLink.dispatchEvent(downloadEvt);
} else if (document.createEventObject) {
downloadLink.fireEvent('onclick');
} else if (typeof downloadLink.onclick == 'function') {
downloadLink.onclick();
}
document.body.removeChild(downloadLink);
}
}
const isPCBroswer = () => {
let e = window.navigator.userAgent.toLowerCase()
, t = "ipad" == e.match(/ipad/i)
, i = "iphone" == e.match(/iphone/i)
, r = "midp" == e.match(/midp/i)
, n = "rv:1.2.3.4" == e.match(/rv:1.2.3.4/i)
, a = "ucweb" == e.match(/ucweb/i)
, o = "android" == e.match(/android/i)
, s = "windows ce" == e.match(/windows ce/i)
, l = "windows mobile" == e.match(/windows mobile/i);
return !(t || i || r || n || a || o || s || l)
}
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
const telFormat = (tel) => {
// 第一种:正则表达式
const result = tel.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
// 第二种:字符串 substring 方法
/* 利用replace()方法,将电话号码中符合条件的部分替换成 ****,
条件就是 tel.substring(3,7) 截取的中间四位字符串 */
const result = tel.replace(tel.substring(3,7), "****");
// 第三种:字符串substr方法
// 截取字符串的前三项 + **** + 截取字符串的第七项之后的字符串
const result = tel.substr(0,3) + "****" + tel.substr(7);
}
telFormat(13612345678) // 136****5678
const getKebabCase = (str) => {
return str.replace(/[A-Z]/g, (item) => '-' + item.toLowerCase())
}
getKebabCase('firstCodeHelloWorld')
// first-code-hello-world
const getCamelCase = (str) => {
return str.replace( /-([a-z])/g, (i, item) => item.toUpperCase())
}
getCamelCase('first-code-hello-world')
// firstCodeHelloWorld
在JavaScript中,工具函数(也称为实用函数或辅助函数)是用来解决日常编程任务的函数。它们通常不是用于实现应用程序的主要功能,而是提供一些实用的功能,使开发人员的工作更加轻松。
本篇文章就先分享到这里,更多精彩内容,您可以关注作者及时获取后续的最新文章内容!文中有错误的地方,欢迎大家批评指正,谢谢您的观看。