UNPKG

@emrys-cloud/eutils

Version:

Emrys云常用的 JavaScript 工具函数库

1,003 lines (990 loc) 28.5 kB
/** * @file 类型相关api */ /** * 判断值是否为 null * @param {unknown} value * @returns {value is null} * * @example * isNull(null) // => true * isNull('') // => false */ const isNull = (value) => { return Object.prototype.toString.call(value) === '[object Null]'; }; /** * 判断值是否为 undefined * @param {unknown} value * @returns {value is undefined} * * @example * isUndefined(undefined) // => true * isUndefined('') // => false */ const isUndefined = (value) => { return Object.prototype.toString.call(value) === '[object Undefined]'; }; /** * 判断值是否为 Number * @param {unknown} value * @returns {value is number} * * @example * isNumber(123) // => true * isNumber('') // => false */ const isNumber = (value) => { return Object.prototype.toString.call(value) === '[object Number]'; }; /** * 判断值是否为 Boolean * @param {unknown} value * @returns {value is boolean} * * @example * isBoolean(true) // => true * isBoolean(1) // => false */ const isBoolean = (value) => { return Object.prototype.toString.call(value) === '[object Boolean]'; }; /** * 判断值是否为 String * @param {unknown} value * @returns {value is string} * * @example * isString('1') // => true * isString(1) // => false */ const isString = (value) => { return Object.prototype.toString.call(value) === '[object String]'; }; /** * 判断值是否为 Object * @param {unknown} value * @returns {value is object} * * @example * isObject({}) // => true * isObject(1) // => false */ const isObject = (value) => { return Object.prototype.toString.call(value) === '[object Object]'; }; /** * 判断值是否为 Array * @param {unknown} value * @returns {value is unknown[]} * * @example * isArray([]) // => true * isArray({}) // => false */ const isArray = (value) => { return Object.prototype.toString.call(value) === '[object Array]'; }; /** * 判断值是否为 Function * @param {unknown} value * @returns {value is Function} * * @example * isFunction(()=>{}) // => true * isFunction(1) // => false */ const isFunction = (value) => { return Object.prototype.toString.call(value) === '[object Function]'; }; /** * 判断值是否为 Date * @param {unknown} value * @returns {value is Date} * * @example * isDate(new Date()) // => true * isDate(1123234234234) // => false */ const isDate = (value) => { return Object.prototype.toString.call(value) === '[object Date]'; }; /** * 判断值是否为 正则 RegExp * @param {unknown} value * @returns {value is Date} * * @example * isRegExp(new RegExp()) // => true * isRegExp(/a-z/) // => true * isRegExp(1) // => false */ const isRegExp = (value) => { return Object.prototype.toString.call(value) === '[object RegExp]'; }; /** * 判断值是否为 Symbol * @param {unknown} value * @returns {value is symbol} * * @example * isSymbol(Symbol()) // => true * isSymbol('') // => false */ const isSymbol = (value) => { return Object.prototype.toString.call(value) === '[object Symbol]'; }; /** * 判断值是否为空,包含 undefined、null、空字符串(只有空格的字符串)、空数组、空对象 * @param {unknown} value 要判断的数据 * @returns {value is void} * * @example * isEmpty(' ') // => true * isEmpty({}) // => true * isEmpty(0) // => false */ const isEmpty = (value) => { if (isUndefined(value) || isNull(value) || (isString(value) && value.replace(/(^\s*)|(\s*$)/g, '').length === 0) || (isObject(value) && !Object.keys(value).length) || (isArray(value) && !value.length)) { return true; } return false; }; /** * 判断值是否不为空,与isEmpty取反 * @param {unknown} value 要判断的数据 * @returns {boolean} * * @example * isNotEmpty(0) // => true * isNotEmpty(' ') // => false * isNotEmpty({}) // => false */ const isNotEmpty = (value) => { return !isEmpty(value); }; /** * @file 字符串相关api */ /** * 使用符号遮蔽指定位置的字符串 * @param {string} str 需要处理的字符串 * @param {number} start 起始位置index * @param {number} end 结束位置index * @param {string} _mask 要替换成的字符,默认为 * * @returns {string} 返回遮蔽后的字符串 * * @example * mask('12398765432', 3, 7) // => "123****5432" * mask('12398765432', 3, 7, '-') // => "123----5432" */ const mask = (str, start = 0, end = 0, _mask = '*') => { let reg = new RegExp(`\^\(\.\{${start}\}\)\(\.\{${end - start}\}\)\(\.${end >= str.length ? '?' : '+'}\)\$`); return str.replace(reg, (_$0, $1, $2, $3) => $1 + $2.replace(/./g, _mask) + $3); }; /** * 使用符号遮蔽从最左边到指定位置(从左往右)的字符串 * @param {string} str * @param {number} end 结束位置(从左往右) * @param {string} _mask 要替换成的字符,默认为 * * @returns {string} 返回遮蔽后的字符串 * * @example * maskLeft('12398765432', 3, '-') // "---98765432" */ const maskLeft = (str, end = 0, _mask = '*') => mask(str, 0, end, _mask); /** * 使用符号遮蔽从最右边到指定位置(从右往左)的字符串 * @param {string} str * @param {number} end 结束位置(从右边起) * @param {string} _mask 要替换成的字符,默认为 * * @returns {string} 返回遮蔽后的字符串 * * @example * maskRight('12398765432', 3, '-') // => "12398765---" */ const maskRight = (str, end = 0, _mask = '*') => { let strLenth = str.length; return mask(str, end > strLenth ? 0 : strLenth - end, strLenth, _mask); }; /** * @file 数字相关api */ /** * 判断数字是否为整数 * @param num * @returns {boolean} * * @example * numIsInt(1) // => true * numIsInt(1.1) // => false */ const numIsInt = (num) => { if (!isNumber(num) || isNaN(num)) { return false; } return ~~num === num; }; /** * 判断数字是否为浮点型 * @param num * @returns {boolean} * * @example * numIsFloat(1.1) // => true * numIsFloat(1) // => false */ const numIsFloat = (num) => { if (!isNumber(num) || isNaN(num)) { return false; } return num % 1 != 0; }; /** * 返回指定范围内的随机数(整数) * @param {number} min 最小值 * @param {number} max 最大值 * @returns {number} 在范围内的随机整数 * * @example * randomInt(5,10) // => 5 || 6 || 7 || 8 || 9 || 10 */ const randomInt = (min, max) => { if (isNaN(min) || isNaN(max)) { throw Error('range must be number'); } if (numIsFloat(min) || numIsFloat(max)) { throw Error('range must be int'); } if (min > max) { throw Error('range min must be less than range max'); } return Math.floor(Math.random() * (max - min + 1)) + min; }; /** * 将数字四舍五入到指定的小数位数 * @param {number} n 操作的数字 * @param {number} decimals 精确到几位小数 * @returns {number} 四舍五入后的数 * * @example * round(12.555,2) // => 12.56 */ const round = (n, decimals = 0) => { return Number(`${Math.round(Number(`${n}e${decimals}`))}e-${decimals}`); }; function sumBy(arr, fn) { return arr .map(typeof fn === 'function' ? fn : val => val[fn]) .reduce((acc, val) => addNum(acc, val), 0); } /** * 返回数字数组中元素之和(两个或两个以上数字) * @param {Array} arr 操作的数组 * @returns {number} 数组元素之和 * * @example * sum([1,2,3,4,5]) // => 15 */ const sum = (arr) => sumBy(arr, row => row); /** * 将数字转化为千分位格式,可以在数字前面加上符号 * @param {number} num * @param {string} mark * @returns {string} * * @example * toDecimalMark(12345674654.123,'¥') // => "¥12,345,674,654.123" */ const toDecimalMark = (num, mark = '') => num.toLocaleString('en-US').replace(/^/, mark); /** * 加法运算(解决浮点数计算问题) * @param {number} a * @param {number} b * @returns {number} 返回正确相加后的数 * * @example * addNum(0.3 , 0.6) // => 0.9 */ const addNum = (a, b) => { var c, d, e; try { c = a.toString().split('.')[1].length; } catch (f) { c = 0; } try { d = b.toString().split('.')[1].length; } catch (f) { d = 0; } return (e = Math.pow(10, Math.max(c, d))), (mulNum(a, e) + mulNum(b, e)) / e; }; /** * 减法运算(解决浮点数计算问题) * @param {number} a 被减数 * @param {number} b 减数 * @returns {number} 返回正确相减后的数 * * @example * subNum(0.3 , 0.2) // => 0.1 */ const subNum = (a, b) => { var c, d, e; try { c = a.toString().split('.')[1].length; } catch (f) { c = 0; } try { d = b.toString().split('.')[1].length; } catch (f) { d = 0; } return (e = Math.pow(10, Math.max(c, d))), (mulNum(a, e) - mulNum(b, e)) / e; }; /** * 乘法运算(解决浮点数计算问题) * @param {number} a * @param {number} b * @returns {number} 返回正确相乘后的数 * * @example * mulNum(0.3 , 1.5) // => 0.45 */ const mulNum = (a, b) => { var c = 0, d = a.toString(), e = b.toString(); try { c += d.split('.')[1].length; } catch (f) { } try { c += e.split('.')[1].length; } catch (f) { } return (Number(d.replace('.', '')) * Number(e.replace('.', ''))) / Math.pow(10, c); }; /** * 除法运算(解决浮点数计算问题) * @param {number} a 被除数 * @param {number} b 除数 * @returns {number} 返回正确相除后的数 * * @example * divNum(0.3 , 0.1) // => 3 */ const divNum = (a, b) => { var c, d, e = 0, f = 0; try { e = a.toString().split('.')[1].length; } catch (g) { } try { f = b.toString().split('.')[1].length; } catch (g) { } return ((c = Number(a.toString().replace('.', ''))), (d = Number(b.toString().replace('.', ''))), mulNum(c / d, Math.pow(10, f - e))); }; /** * @file 对象相关api */ /** * 深克隆(深拷贝) * @param {*} value * @returns {*} 返回深克隆(深拷贝)后的值 * * @example * deepClone(1) // => 1 * deepClone({a: 1, b: 2}) // => {a: 1, b: 2} */ const deepClone = (value) => { if (isEmpty(value) || typeof value !== 'object') return value; if (isDate(value)) { return new Date(new Date().setTime(value.getTime())); } if (isArray(value)) { return value.map(row => deepClone(row)); } if (isObject(value)) { let copy = {}; for (const attr in value) { if (value.hasOwnProperty(attr)) copy[attr] = deepClone(value[attr]); } return copy; } return value; }; /** * @file 数组相关api */ /** * 数组去重 - 普通 * @param {array} arr 去重的数组 * @returns {array} 不影响原数组,返回过滤后的新数组 * * @example * unique([1,2,2,3,4,3,4,7]) // => [1, 2, 3, 4, 7] */ const unique = (arr) => [...new Set(arr)]; /** * 数组去重 - 根据数组里的对象里的某个key值去重 * @param {array} arr 要去重的数组 * @param {string} key 要作为去重判断的key * @returns {array} 不影响原数组,返回过滤后的新数组 * * @example * uniqueBy([{name:'1111'},{name:'1111'},{name:'222'}],'name') // => [{name:'1111'},{name:'222'} */ const uniqueBy = (arr, key) => { return arr.filter((element, index, array) => array.findIndex(row => row[key] === element[key]) === index); }; /** * 获取数组中的最大值 * @param {number[]} arr * @returns {number} 返回最大值 * * @example * maxNum([12,3,31,5,3]) // => 31 */ const maxNum = (arr) => Math.max.apply(Math, arr); /** * 获取数组中的最小值 * @param {number[]} arr * @returns {number} 返回最小值 * * @example * minNum([12,3,31,5,3]) // => 3 */ const minNum = (arr) => Math.min.apply(Math, arr); /** * 打乱数组 * @param {unknown[]} arr * @returns {array} 影响原数组,返回打乱后的数组 * * @example * shuffle([1, 3, 5, 7, 8]) // => [7, 1, 5, 8, 3] */ const shuffle = (arr) => { let i = arr.length; while (i) { let j = Math.floor(Math.random() * i--); [arr[j], arr[i]] = [arr[i], arr[j]]; } return arr; }; /** * 扁平化数组 ==> 树形结构。 pid 为空时(使用isEmpty判断或者为0时),代表是一级 * @param {array} list 扁平数组 * @param {object} options 配置 * @param {string} options.id 当前节点代表自己ID的key * @param {string} options.pid 当前接待代表父级ID的key * @param {string} options.childKey 当前节点子级树存放的key * @returns {array} 不影响原数组,返回处理后的数组 * * @example * flatToTree([{"id":"2","rank":1,"pid":""},{"id":"2.1","rank":2,"pid":"2"}], {id: 'id', pid: 'pid', childKey: 'children'}) // => [{"id":"2","rank":1,"pid":"","children":[{"id":"2.1","rank":2,"pid":"2","children":[]}]}] */ const flatToTree = (list, options) => { let { childKey, pid, id } = options; const newArr = deepClone(list); return newArr.filter(item => { var child = newArr.filter(child => child[pid] === item[id]); item[childKey] = child; return isEmpty(item[pid]) || item[pid] === 0; }); }; /** * 树形结构 ==> 扁平化数组。 会删除 childKey 的键名 * @param {Array} array 数组 * @param {String} childKey 子集数组名 * @returns {array} 不影响原数组,返回处理后的数组 * * @example * treeToFlat([{"id":"2","rank":1,"children":[{"id":"2.1","rank":2}]}], 'children') // => [{"id":"2","rank":1},{"id":"2.1","rank":2}] */ const treeToFlat = (arr, childKey) => { let newArr = []; function getData(list) { list.forEach(item => { const newItem = deepClone(item); delete newItem[childKey]; newArr.push(newItem); if (isNotEmpty(item[childKey])) { getData(item[childKey]); } }); } getData(arr); return newArr; }; /** * @file 函数相关api */ /** * 防抖 * @param {Function} fn 要执行的函数 * @param {number} [wait = 50] 等待执行的毫秒数 * @param {boolean} [immediate = false] 是否立即执行 * @returns {Function} 返回防抖处理后的函数 * * @example * debounce(() => { console.log(1) }, 200) * debounce(() => { console.log(1) }, 100, true) */ const debounce = (fn, wait, immediate) => { if (!wait) { wait = 50; } let timer; return function () { if (timer) clearTimeout(timer); if (immediate) { if (!timer) fn.apply(this, arguments); timer = setTimeout(() => { timer = null; }, wait); } else { timer = setTimeout(() => { fn.apply(this, arguments); }, wait); } }; }; /** * 节流 * @param {Function} fn 要执行的函数 * @param {number} [wait = 50] 等待执行的毫秒数 * @returns {Function} 返回节流处理后的函数 * * @example * throttle(() => { console.log(1) }, 200) */ const throttle = (fn, wait) => { if (!wait) { wait = 50; } let prev = new Date().getTime(); return function () { const now = new Date().getTime(); if (now - prev > wait) { fn.apply(this, arguments); prev = now; } }; }; /** * @file 获取设备、浏览器、操作系统相关信息 */ /** * 判断是否为 IE */ const isIE = () => !!window.ActiveXObject || 'ActiveXObject' in window; /** * 判断是否为 IE 11 */ const isIE11 = () => navigator.userAgent.toLowerCase().match(/rv:([\d.]+)\) like gecko/); /** * 判断是否为 Edge */ const isEdge = () => /Edge/.test(navigator.userAgent); /** * 判断是否为 Firefox */ const isFirefox = () => /Firefox/.test(navigator.userAgent); /** * 判断是否为 Opera */ const isOpera = () => /Opera/.test(navigator.userAgent); /** * 判断是否为 Safari */ const isSafari = () => /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); /** * 判断是否为 Chrome */ const isChrome = () => /Chrome/.test(navigator.userAgent); /** * 判断是否为 移动端 */ const isMobile = () => navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i); /** * 判断是否为 PC */ const isPC = () => !isMobile(); /** * 判断是否为 Windows */ const isWindows = () => /win/i.test(navigator.appVersion.toLowerCase()); /** * 判断是否为 Mac */ const isMac = () => /mac/i.test(navigator.appVersion.toLowerCase()); /** * 判断是否为 Linux */ const isLinux = () => /linux/i.test(navigator.appVersion.toLowerCase()); /** * 判断是否为 安卓 */ const isAndroid = () => navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Linux') > -1; /** * 判断是否为 IOS */ const isIOS = () => !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); /** * 判断是否为 微信 */ const isWx = () => navigator.userAgent.match(/MicroMessenger/gi); /** * 判断是否为 QQ */ const isQQ = () => { const ua = navigator.userAgent.toLowerCase(); if (isIOS()) { return ua.indexOf(' qq') > -1 && ua.indexOf('mqqbrowser') < 0; } else if (isAndroid()) { return ua.indexOf(' qq') > -1 && ua.indexOf('mqqbrowser') > -1; } return false; }; /** * 判断是否为 阿里 */ const isAli = () => navigator.userAgent.match(/AlipayClient/gi); /** * @file 文件流相关api */ /** * 将 file、blob、stream 格式 转 DateURL * @param {Blob | File } blob * @returns {Promise<string | ArrayBuffer | null>} */ const blobToDataURL = (blob) => { return new Promise((resolve, reject) => { let reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = () => { resolve(reader.result); }; reader.onerror = err => { reject(err); }; }); }; /** * 将图片的 dataURL 转为 Blob 格式 * @param {String} dataURL * @returns {Blob} */ const dataURLtoBlob = (dataURL) => { let arr = dataURL.split(','); let mime = arr[0].match(/:(.*?);/)[1]; let bstr = atob(arr[1]); let n = bstr.length; let u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }; /** * 将图片的 url 转为 base64 格式 * @param {string} url * @returns {Promise<string>} */ const getImgToBase64 = (url) => { return new Promise((resolve, reject) => { let canvas = document.createElement('canvas'); let ctx = canvas.getContext('2d'); let img = new Image(); img.crossOrigin = 'Anonymous'; img.onload = function () { canvas.height = img.height; canvas.width = img.width; ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL('image/jpg'); resolve(dataURL); canvas = null; }; img.onerror = err => reject(err); img.src = url; }); }; /** * 将图片的 url 转为 Blob 格式 * @param {string} url * @returns {Promise<Blob>} */ const getImgToBlob = (url) => { return new Promise((resolve, reject) => { getImgToBase64(url) .then(dataURL => { resolve(dataURLtoBlob(dataURL)); }) .catch(err => { reject(err); }); }); }; /** * 触发文件下载 - 使用a标签 * @param {string} fileName * @param {BlobPart | File} content * @param {string} type * @returns {void} */ const downloadFile = (fileName, content, type = 'text/plain') => { var el = document.createElement('a'); var blob = new Blob([content], { type }); el.href = URL.createObjectURL(blob); el.download = fileName; el.addEventListener('click', e => e.stopImmediatePropagation()); document.body.appendChild(el); el.click(); document.body.removeChild(el); }; /** * @file url相关api */ /** * * url参数 => 对象 * @param {string} [url = window.location.href] default: window.location.href * @return {object} * * @example * parseQueryString('www.baidu.com?id=1&name=tom') // => {id: "1", name: "tom"} * parseQueryString('www.baidu.com?') // => {} */ const parseQueryString = (url) => { url = isEmpty(url) ? window.location.href : url; if (url.indexOf('?') === -1) { return {}; } var search = url[0] === '?' ? url.substr(1) : url.substring(url.lastIndexOf('?') + 1); if (search === '') { return {}; } let searchArr = search.split('&'); var query = {}; for (var i = 0; i < searchArr.length; i++) { var pair = searchArr[i].split('='); query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || ''); } return query; }; /** * 对象 => url参数 * @param {object} obj * @return {string} * * @example * stringfyQueryString({id: 1, name: 'tom'}) // => 'id=1&name=tom' * stringfyQueryString({}) // => '' * stringfyQueryString() // => '' */ const stringfyQueryString = (obj) => { if (isEmpty(obj)) return ''; var pairs = []; for (var key in obj) { var value = obj[key]; if (isArray(value)) { for (var i = 0; i < value.length; ++i) { pairs.push(encodeURIComponent(key + '[' + i + ']') + '=' + encodeURIComponent(value[i])); } continue; } pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])); } return pairs.join('&'); }; /** * 获取URL参数中某个属性的值 * @param {string} key 要取值的属性名 * @returns {string | null} url中该参数的值 * * @example * window.location.href = 'www.baidu.com?name=tom' * getQueryByKey('name') // => 'tom' * getQueryByKey('age') // => '' * getQueryByKey('') // => '' */ const getQueryByKey = (key) => { const query = window.location.href.split('?')[1] || ''; const vars = query.split('&'); for (let i = 0; i < vars.length; i++) { const pair = vars[i].split('='); if (pair[0] == key) { return pair[1]; } } return null; }; /** * @file 剪贴板相关 */ /** * 复制文本数据到剪贴板 * @param {string} text * @returns {Promise<void>} 返回一个promise,resolve即为成功 */ const copyTextToClipboard = (text) => { return new Promise((resolve, reject) => { let url = text; var textarea = document.createElement('textarea'); var currentFocus = document.activeElement; document.body.appendChild(textarea); textarea.value = url; textarea.focus(); if (textarea.setSelectionRange) { textarea.setSelectionRange(0, textarea.value.length); } else { textarea.select(); } try { document.execCommand('copy'); resolve(); } catch (err) { reject(); } document.body.removeChild(textarea); currentFocus.focus(); }); }; /** * @file 页面适配相关API */ /** * rem适配用,设置html字体大小,css单位使用rem做自适应 * @param portPixel 竖屏时宽度,默认为750 * @param landPixel 横屏时宽度,默认为1334 */ const remAdapt = (portPixel = 750, landPixel = 1334) => { if (!window.addEventListener) return; function setFont() { var html = document.documentElement; var k = portPixel; var w = document.documentElement.clientWidth, h = document.documentElement.clientHeight; if (w > h) { k = landPixel; document.documentElement.setAttribute('class', 'landscape'); } if (w < h) { k = portPixel; document.documentElement.setAttribute('class', 'portrait'); } html.style.fontSize = (html.clientWidth / k) * 100 + 'px'; } setFont(); setTimeout(function () { setFont(); }, 300); document.addEventListener('DOMContentLoaded', setFont, false); window.addEventListener('orientationchange', setFont, false); window.addEventListener('resize', setFont, false); window.addEventListener('load', setFont, false); }; /** * @file Storage存储相关 * @description 能以对象的形式存取缓存 */ // 公用缓存,目前只支持存取 object 对象 const cache = {}; const storageObj = { '0': localStorage, '1': sessionStorage, }; /** * 获取缓存 * @param {string} key 缓存的key值 * @param {string} type 缓存类型 0=localStorage 1=sessionStorage * @returns {object | string} 返回缓存的值,对象或字符串类型 */ const getItem = (key, type = '1') => { let cacheResult = cache[key]; if (cacheResult) return cacheResult; let result = storageObj[type].getItem(key); if (result) { result = JSON.parse(result); if (result && result.__storageType === 'string') { result = result.value; } } else { result = ''; } cache[key] = result; return result; }; /** * 设置缓存 * @param {string} key 缓存的key值 * @param {string | object} value 缓存的值 * @param {string} type 缓存类型 0=localStorage 1=sessionStorage */ const setItem = (key, value = {}, type = '1') => { cache[key] = value; if (typeof value === 'string') { value = { __storageType: 'string', value, }; } const str = JSON.stringify(value); storageObj[type].setItem(key, str); }; /** * 删除缓存 * @param {string} key 缓存的key值 * @param {string} type 缓存类型 0=localStorage 1=sessionStorage */ const removeItem = (key, type = '1') => { cache[key] = ''; storageObj[type].removeItem(key); }; /** * 设置缓存 - 纯字符串形式 * @param {string} key 缓存的key值 * @param {string} value 要缓存的值 * @param {string} type 缓存类型 0=localStorage 1=sessionStorage */ const setString = (key, value = '', type = '1') => { cache[key] = value; storageObj[type].setItem(key, value); }; /** * 获取缓存 - 纯字符串形式 * @param {string} key 缓存的key值 * @param {string} type 缓存类型 0=localStorage 1=sessionStorage * @returns {string | null} 返回缓存的值,字符串类型 */ const getString = (key, type = '1') => { let result = cache[key]; if (!result) { result = storageObj[type].getItem(key); cache[key] = result; } return result; }; export { addNum, blobToDataURL, copyTextToClipboard, dataURLtoBlob, debounce, deepClone, divNum, downloadFile, flatToTree, getImgToBase64, getImgToBlob, getItem, getQueryByKey, getString, isAli, isAndroid, isArray, isBoolean, isChrome, isDate, isEdge, isEmpty, isFirefox, isFunction, isIE, isIE11, isIOS, isLinux, isMac, isMobile, isNotEmpty, isNull, isNumber, isObject, isOpera, isPC, isQQ, isRegExp, isSafari, isString, isSymbol, isUndefined, isWindows, isWx, mask, maskLeft, maskRight, maxNum, minNum, mulNum, numIsFloat, numIsInt, parseQueryString, randomInt, remAdapt, removeItem, round, setItem, setString, shuffle, stringfyQueryString, subNum, sum, sumBy, throttle, toDecimalMark, treeToFlat, unique, uniqueBy };