UNPKG

cnwy-js-util

Version:

js常见的函数工具库

339 lines (318 loc) 10.3 kB
// 可遍历类型 Map Set Object Array const typeMap = '[object Map]'; const typeSet = '[object Set]'; const typeObject = '[object Object]'; const typeArray = '[object Array]'; // 非原始类型的 不可遍历类型 Date RegExp Function const typeDate = '[object Date]'; const typeRegExp = '[object RegExp]'; const typeFunction = '[object Function]'; // 非原始类型的 不可遍历类型的 集合(原始类型已经被过滤了不用再考虑了) const simpleType = [typeDate, typeRegExp, typeFunction]; // 是否是引用类型 const isObject = target => { if (target === null) { return false; } else { const type = typeof target; return type === 'object' || type === 'function'; } }; // 获取标准类型 const getType = target => { return Object.prototype.toString.call(target); }; /* * 1、处理原始类型 Number String Boolean Symbol Null Undefined * 2、处理不可遍历类型 Date RegExp Function * 3、处理循环引用情况 WeakMap * 4、处理可遍历类型 Set Map Array Object * */ export function deepCopy(target, map = new WeakMap()) { // 处理原始类型直接返回(Number BigInt String Boolean Symbol Undefined Null) if (!isObject(target)) { return target; } // 处理不可遍历类型 const type = getType(target); if (simpleType.includes(type)) { switch (type) { case typeDate: // 日期 return new Date(target); case typeRegExp: // 正则 const reg = /\w*$/; const result = new RegExp(target.source, reg.exec(target)[0]); result.lastIndex = target.lastIndex; // lastIndex 表示每次匹配时的开始位置 return result; case typeFunction: // 函数 return target; default: return target; } } // 用于返回 let cloneTarget; // 处理循环引用 if (map.get(target)) { // 已经放入过map的直接返回 return map.get(target); } // 处理可遍历类型 switch (type) { case typeSet: // Set cloneTarget = new Set(); map.set(target, cloneTarget); target.forEach(item => { cloneTarget.add(deepCopy(item, map)); }); return cloneTarget; case typeMap: // Map cloneTarget = new Map(); map.set(target, cloneTarget); target.forEach((value, key) => { cloneTarget.set(key, deepCopy(value, map)); }); return cloneTarget; case typeArray: // 数组 cloneTarget = []; map.set(target, cloneTarget); target.forEach((item, index) => { cloneTarget[index] = deepCopy(item, map); }); return cloneTarget; case typeObject: // 对象 cloneTarget = {}; map.set(target, cloneTarget); [...Object.keys(target), ...Object.getOwnPropertySymbols(target)].forEach(item => { cloneTarget[item] = deepCopy(target[item], map); }); return cloneTarget; default: return target; } } //数组扁平化 export const flat = arr => { return arr.reduce((pre, cur) => { return pre.concat(Array.isArray(cur) ? flat(cur) : cur); }, []); }; //数组去重 export function unique(arr) { let append = new Set(); return arr.filter(item => { //创建一个可以唯一标识对象的字符串id let id = item + JSON.stringify(item); if (append.has(id)) { return false; } else { append.add(id); return true; } }); } /** * @param {Array} arr * @returns {Array} */ export function uniqueArr(arr) { return Array.from(new Set(arr)); } // 获取url参数 export function getQueryObject(url) { url = url == null ? window.location.href : url; const search = url.substring(url.lastIndexOf('?') + 1); const obj = {}; const reg = /([^?&=]+)=([^?&=]*)/g; search.replace(reg, (rs, $1, $2) => { const name = decodeURIComponent($1); let val = decodeURIComponent($2); val = String(val); obj[name] = val; return rs; }); return obj; } /** * @name 查看附件 doc, docx, xls, xlsx, ppt, pptx 格式 * @param {string<url>} url */ export function handleViewFile(url) { const filtType = getFileExtensionFromUrl(url); const openOfficeAppList = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']; if (openOfficeAppList.includes(filtType)) { window.open( 'https://view.officeapps.live.com/op/view.aspx?src=' + encodeURIComponent(url), '_blank', 'noopener,noreferrer' ); } else { window.open(url, '_blank', 'noopener,noreferrer'); } } // 导出一个生成随机密码的函数 export function generateRandomPassword() { // 定义大写字母集合 const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // 定义小写字母集合 const lower = 'abcdefghijklmnopqrstuvwxyz'; // 定义数字集合 const digits = '0123456789'; // 初始化密码字符串 let password = ''; // 初始化是否有大写字母的变量 let hasUpper = false; // 初始化是否有小写字母的变量 let hasLower = false; // 初始化是否有数字的变量 let hasDigit = false; // 循环直到密码中包含大写字母、小写字母和数字 while (password.length <= 8) { // 如果没有大写字母,则随机选择一个大写字母添加到密码中,并将hasUpper设置为true if (!hasUpper) { password += upper.charAt(Math.floor(Math.random() * upper.length)); hasUpper = true; } else if (!hasLower) { // 如果没有小写字母,则随机选择一个小写字母添加到密码中,并将hasLower设置为true password += lower.charAt(Math.floor(Math.random() * lower.length)); hasLower = true; } else if (!hasDigit) { // 如果没有数字,则随机选择一个数字添加到密码中,并将hasDigit设置为true password += digits.charAt(Math.floor(Math.random() * digits.length)); hasDigit = true; } else { // 如果密码中已经包含大写字母、小写字母和数字,则随机选择任意一种字符添加到密码中 const allChars = upper + lower + digits; password += allChars.charAt(Math.floor(Math.random() * allChars.length)); } } // 截取密码长度为8位,并返回结果 return password.slice(0, 8); } /** * @param {Object} json * @returns {Array} */ export function param(json) { if (!json) return ''; return cleanArray( Object.keys(json).map(key => { if (json[key] === undefined) return ''; return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]); }) ).join('&'); } /** * @param {string} url * @returns {Object} */ export function param2Obj(url) { const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' '); if (!search) { return {}; } const obj = {}; const searchArr = search.split('&'); searchArr.forEach(v => { const index = v.indexOf('='); if (index !== -1) { const name = v.substring(0, index); const val = v.substring(index + 1, v.length); obj[name] = val; } }); return obj; } /** * @param {string} val * @returns {string} */ export function html2Text(val) { const div = document.createElement('div'); div.innerHTML = val; return div.textContent || div.innerText; } /** * Merges two objects, giving the last one precedence * @param {Object} target * @param {(Object|Array)} source * @returns {Object} */ export function objectMerge(target, source) { if (typeof target !== 'object') { target = {}; } if (Array.isArray(source)) { return source.slice(); } Object.keys(source).forEach(property => { const sourceProperty = source[property]; if (typeof sourceProperty === 'object') { target[property] = objectMerge(target[property], sourceProperty); } else { target[property] = sourceProperty; } }); return target; } /** * @param {HTMLElement} element * @param {string} className */ export function toggleClass(element, className) { if (!element || !className) { return; } let classString = element.className; const nameIndex = classString.indexOf(className); if (nameIndex === -1) { classString += '' + className; } else { classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length); } element.className = classString; } export function makeMap(str, expectsLowerCase) { const map = Object.create(null); const list = str.split(','); for (let i = 0; i < list.length; i++) { map[list[i]] = true; } return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val]; } // 首字母大写 export function titleCase(str) { return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()); } // 下划转驼峰 export function camelCase(str) { return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()); } export function isNumberStr(str) { return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str); } /** * @name 从URL中获取文件扩展名 * @param {string} url - 待处理的URL * @returns {string} - 文件扩展名 */ export function getFileExtensionFromUrl(url) { const path = url.split('?')[0]; // 去除可能存在的查询参数 return path.substring(path.lastIndexOf('.') + 1); } /** * @returns {string} */ export function createUniqueString() { const timestamp = +new Date() + ''; const randomNum = parseInt((1 + Math.random()) * 65536) + ''; return (+(randomNum + timestamp)).toString(32); }