20 个 JS 工具函数助力高效开发
Posted 前端开发博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20 个 JS 工具函数助力高效开发相关的知识,希望对你有一定的参考价值。
前言
日常开发中,面对各种不同的需求,我们经常会用到以前开发过的一些工具函数,把这些工具函数收集起来,将大大提高我们的开发效率。
1、校验数据类型
export const typeOf = function(obj)
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
复制代码
示例:
typeOf('树哥') // string
typeOf([]) // array
typeOf(new Date()) // date
typeOf(null) // null
typeOf(true) // boolean
typeOf(() => ) // function
复制代码
2、防抖
export const debounce = (() =>
let timer = null
return (callback, wait = 800) =>
timer&&clearTimeout(timer)
timer = setTimeout(callback, wait)
)()
复制代码
示例:
如 vue 中使用
methods:
loadList()
debounce(() =>
console.log('加载数据')
, 500)
复制代码
3、节流
export const throttle = (() =>
let last = 0
return (callback, wait = 800) =>
let now = +new Date()
if (now - last > wait)
callback()
last = now
)()
复制代码
4、手机号脱敏
export const hideMobile = (mobile) =>
return mobile.replace(/^(\\d3)\\d4(\\d4)$/, "$1****$2")
复制代码
5、开启全屏
export const launchFullscreen = (element) =>
if (element.requestFullscreen)
element.requestFullscreen()
else if (element.mozRequestFullScreen)
element.mozRequestFullScreen()
else if (element.msRequestFullscreen)
element.msRequestFullscreen()
else if (element.webkitRequestFullscreen)
element.webkitRequestFullScreen()
复制代码
6、关闭全屏
export const exitFullscreen = () =>
if (document.exitFullscreen)
document.exitFullscreen()
else if (document.msExitFullscreen)
document.msExitFullscreen()
else if (document.mozCancelFullScreen)
document.mozCancelFullScreen()
else if (document.webkitExitFullscreen)
document.webkitExitFullscreen()
复制代码
7、大小写转换
参数:
str 待转换的字符串
type 1-全大写 2-全小写 3-首字母大写
export const turnCase = (str, type) =>
switch (type)
case 1:
return str.toUpperCase()
case 2:
return str.toLowerCase()
case 3:
//return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
return str[0].toUpperCase() + str.substring(1).toLowerCase()
default:
return str
复制代码
示例:
turnCase('vue', 1) // VUE
turnCase('REACT', 2) // react
turnCase('vue', 3) // Vue
复制代码
8、解析URL参数
export const getSearchParams = () =>
const searchPar = new URLSearchParams(window.location.search)
const paramsObj =
for (const [key, value] of searchPar.entries())
paramsObj[key] = value
return paramsObj
复制代码
示例:
// 假设目前位于 https://****com/index?id=154513&age=18;
getSearchParams(); // id: "154513", age: "18"
复制代码
9、判断手机是Andoird还是ios
/**
* 1: ios
* 2: android
* 3: 其它
*/
export const getOSType=() =>
let u = navigator.userAgent, app = navigator.appVersion;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
let isIOS = !!u.match(/\\(i[^;]+;( U;)? CPU.+Mac OS X/);
if (isIOS)
return 1;
if (isAndroid)
return 2;
return 3;
复制代码
10、数组对象根据字段去重
参数:
arr 要去重的数组
key 根据去重的字段名
export const uniqueArrayObject = (arr = [], key = 'id') =>
if (arr.length === 0) return
let list = []
const map =
arr.forEach((item) =>
if (!map[item[key]])
map[item[key]] = item
)
list = Object.values(map)
return list
复制代码
示例:
const responseList = [
id: 1, name: '树哥' ,
id: 2, name: '黄老爷' ,
id: 3, name: '张麻子' ,
id: 1, name: '黄老爷' ,
id: 2, name: '张麻子' ,
id: 3, name: '树哥' ,
id: 1, name: '树哥' ,
id: 2, name: '黄老爷' ,
id: 3, name: '张麻子' ,
]
uniqueArrayObject(responseList, 'id')
// [ id: 1, name: '树哥' , id: 2, name: '黄老爷' , id: 3, name: '张麻子' ]
复制代码
11、滚动到页面顶部
export const scrollToTop = () =>
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0)
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
复制代码
12、滚动到元素位置
export const smoothScroll = element =>
document.querySelector(element).scrollIntoView(
behavior: 'smooth'
);
;
复制代码
示例:
smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素
复制代码
13、uuid
export const uuid = () =>
const temp_url = URL.createObjectURL(new Blob())
const uuid = temp_url.toString()
URL.revokeObjectURL(temp_url) //释放这个url
return uuid.substring(uuid.lastIndexOf('/') + 1)
复制代码
示例:
uuid() // a640be34-689f-4b98-be77-e3972f9bffdd
复制代码
不过要吐槽一句的是,uuid一般应由后端来进行生成
14、金额格式化
参数:
number number:要格式化的数字
number decimals:保留几位小数
string dec_point:小数点符号
string thousands_sep:千分位符号
export const moneyFormat = (number, decimals, dec_point, thousands_sep) =>
number = (number + '').replace(/[^0-9+-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
const dec = typeof dec_point === 'undefined' ? '.' : dec_point
let s = ''
const toFixedFix = function(n, prec)
const k = Math.pow(10, prec)
return '' + Math.ceil(n * k) / k
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
const re = /(-?\\d+)(\\d3)/
while (re.test(s[0]))
s[0] = s[0].replace(re, '$1' + sep + '$2')
if ((s[1] || '').length < prec)
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
return s.join(dec)
复制代码
示例:
moneyFormat(10000000) // 10,000,000.00
moneyFormat(10000000, 3, '.', '-') // 10-000-000.000
复制代码
15、存储操作
class MyCache
constructor(isLocal = true)
this.storage = isLocal ? localStorage : sessionStorage
setItem(key, value)
if (typeof (value) === 'object') value = JSON.stringify(value)
this.storage.setItem(key, value)
getItem(key)
try
return JSON.parse(this.storage.getItem(key))
catch (err)
return this.storage.getItem(key)
removeItem(key)
this.storage.removeItem(key)
clear()
this.storage.clear()
key(index)
return this.storage.key(index)
length()
return this.storage.length
const localCache = new MyCache()
const sessionCache = new MyCache(false)
export localCache, sessionCache
复制代码
示例:
localCache.getItem('user')
sessionCache.setItem('name','树哥')
sessionCache.getItem('token')
localCache.clear()
复制代码
16、下载文件
参数:
api 接口
params 请求参数
fileName 文件名
const downloadFile = (api, params, fileName, type = 'get') =>
axios(
method: type,
url: api,
responseType: 'blob',
params: params
).then((res) =>
let str = res.headers['content-disposition']
if (!res || !str)
return
let suffix = ''
// 截取文件名和文件类型
if (str.lastIndexOf('.'))
fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
suffix = str.substring(str.lastIndexOf('.'), str.length)
// 如果支持微软的文件下载方式(ie10+浏览器)
if (window.navigator.msSaveBlob)
try
const blobObject = new Blob([res.data]);
window.navigator.msSaveBlob(blobObject, fileName + suffix);
catch (e)
console.log(e);
else
// 其他浏览器
let url = window.URL.createObjectURL(res.data)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName + suffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href);
).catch((err) =>
console.log(err.message);
)
`
复制代码
使用:
downloadFile('/api/download', id, '文件名')
复制代码
17、时间操作
关于时间操作,没必要自己再写一大串代码了,强烈推荐使用 day.js[2]
Day.js 是一个仅 2kb 大小的轻量级 javascript 时间日期处理库,下载、解析和执行的JavaScript更少,为代码留下更多的时间。
18、深拷贝
export const clone = parent =>
// 判断类型
const isType = (obj, type) =>
if (typeof obj !== "object") return false;
const typeString = Object.prototype.toString.call(obj);
let flag;
switch (type)
case "Array":
flag = typeString === "[object Array]";
break;
case "Date":
flag = typeString === "[object Date]";
break;
case "RegExp":
flag = typeString === "[object RegExp]";
break;
default:
flag = false;
return flag;
;
// 处理正则
const getRegExp = re =>
var flags = "";
if (re.global) flags += "g";
if (re.ignoreCase) flags += "i";
if (re.multiline) flags += "m";
return flags;
;
// 维护两个储存循环引用的数组
const parents = [];
const children = [];
const _clone = parent =>
if (parent === null) return null;
if (typeof parent !== "object") return parent;
let child, proto;
if (isType(parent, "Array"))
// 对数组做特殊处理
child = [];
else if (isType(parent, "RegExp"))
// 对正则对象做特殊处理
child = new RegExp(parent.source, getRegExp(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
else if (isType(parent, "Date"))
// 对Date对象做特殊处理
child = new Date(parent.getTime());
else
// 处理对象原型
proto = Object.getPrototypeOf(parent);
// 利用Object.create切断原型链
child = Object.create(proto);
// 处理循环引用
const index = parents.indexOf(parent);
if (index != -1)
// 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
return children[index];
parents.push(parent);
children.push(child);
for (let i in parent)
// 递归
child[i] = _clone(parent[i]);
return child;
;
return _clone(parent);
;
复制代码
此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。
如果确实想要完备的深拷贝,推荐使用 lodash 中的 cloneDeep 方法。
19、模糊搜索
参数:
list 原数组
keyWord 查询的关键词
attribute 数组需要检索属性
export const fuzzyQuery = (list, keyWord, attribute = 'name') =>
const reg = new RegExp(keyWord)
const arr = []
for (let i = 0; i < list.length; i++)
if (reg.test(list[i][attribute]))
arr.push(list[i])
return arr
复制代码
示例:
const list = [
id: 1, name: '树哥' ,
id: 2, name: '黄老爷' ,
id: 3, name: '张麻子' ,
id: 4, name: '汤师爷' ,
id: 5, name: '胡万' ,
id: 6, name: '花姐' ,
id: 7, name: '小梅'
]
fuzzyQuery(list, '树', 'name') // [id: 1, name: '树哥']
复制代码
20、遍历树节点
export const foreachTree = (data, callback, childrenName = 'children') =>
for (let i = 0; i < data.length; i++)
callback(data[i])
if (data[i][childrenName] && data[i][childrenName].length > 0)
foreachTree(data[i][childrenName], callback, childrenName)
复制代码
示例:
假设我们要从树状结构数据中查找 id 为 9 的节点
const treeData = [
id: 1,
label: '一级 1',
children: [
id: 4,
label: '二级 1-1',
children: [
id: 9,
label: '三级 1-1-1'
,
id: 10,
label: '三级 1-1-2'
]
]
,
id: 2,
label: '一级 2',
children: [
id: 5,
label: '二级 2-1'
,
id: 6,
label: '二级 2-2'
]
,
id: 3,
label: '一级 3',
children: [
id: 7,
label: '二级 3-1'
,
id: 8,
label: '二级 3-2'
]
],
let result
foreachTree(data, (item) =>
if (item.id === 9)
result = item
)
console.log('result', result) // id: 9,label: "三级 1-1-1"
复制代码
关于本文
作者:呛再首
https://juejin.cn/post/7132714583399071758
最后
我是小前端,欢迎大家围观我的朋友圈,搞搞技术,吹吹牛逼。我的微信:kujian89,秒添加,邀你进入 500人前端群。
推荐阅读
关注公众号:前端开发博客
回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
回复「Vue脑图」获取 Vue 相关脑图
回复「思维图」获取 JavaScript 相关思维图
回复「简历」获取简历制作建议
回复「简历模板」获取精选的简历模板
回复「加群」进入500人前端精英群
回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
回复「知识点」下载高清JavaScript知识点图谱
👍🏻 点赞 + 在看 支持小编
以上是关于20 个 JS 工具函数助力高效开发的主要内容,如果未能解决你的问题,请参考以下文章