cnwy-js-util
Version:
js常见的函数工具库
339 lines (318 loc) • 10.3 kB
JavaScript
// 可遍历类型 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);
}