javascript工具类函数
1740 字
9 分钟
javascript工具类函数
区分基础类型和对象类型
export const isString = (data) => typeof data === "string";/** * 基础类型判断 * @param value 要判断的数据 */const getBasicType = (value) => typeof value;getBasicType("a"); // stringgetBasicType(456); // numbergetBasicType({}); // objectgetBasicType([]); // object
/** * 类型判断 * @param value 要判断的数据 * @param type 类型 * @return true or false */const isType = (value, type: string): boolean => { const { toString } = {}; return toString.call(value) === `[object ${type}]`;};const getType = (n: Object) => Object.prototype.toString.call(n).slice(8, -1);getType(1); // numbergetType("124"); // StringgetType({}); // ObjectgetType([]); // ArraygetType(Symbol(1)); // Symbol
isType({}, "Object"); // trueisType([], "Object"); // false字符串操作
// 首字母大写const upperFisrtWord = (word = "") => word.slice(0, 1).toUpperCase() + word.slice(1);// 字符串转数组 利用es6扩展运算符// 任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组[..."hello"]; // [ "h", "e", "l", "l", "o" ]深浅拷贝
/** * 浅克隆 * @param source 要浅克隆的目标对象 */const clone = (source: Object) => { if (!source) { return source; } const target = {}; // eslint-disable-next-line guard-for-in for (const k in source) { target[k] = source[k]; } return target;};/** * 深克隆 * @param source 要深克隆的目标对象 */const deepClone = (source: Object | undefined) => { if (!source) { return source; }
const target = new source.constructor();
for (const key in source) { if (source.hasOwnProperty(key)) { target[key] = getType(source[key]) === "Object" || getType(source[key]) === "Array" ? deepClone(source[key]) : source[key]; } }
return target;};判断对象类型的数据是否发生变化
/** * 检测对象属性变化 * @param source 原对象 * @param comparision 改变后的对象 * @param ignoreFields 有些改变了不需要的key */const iterable = (data) => ["Object", "Array"].includes(getType(data));const isObjectChanged = (source, comparision, ignoreFields: string[] = []) => { if (!iterable(source)) return; // 类型不一致 数据已发生变化 if (getType(source) !== getType(comparision)) { console.log(source); console.log(comparision); return true; }
// 获取所有key const sourceKeys = Object.keys(source); // 将对比数据合并到数据源 并提取所有属性名 const comparisonKeys = Object.keys({ ...source, ...comparision });
// 两次key不同直接return if (sourceKeys.length !== comparisonKeys.length) { return true; }
return comparisonKeys.some((key) => { // 对象类型继续递归 if (iterable(source[key])) { return isObjectChanged(source[key], comparision[key], ignoreFields); } else { if (!ignoreFields.includes(key)) { if (source[key] !== comparision[key]) { console.log(key, source[key], comparision[key]); } return source[key] !== comparision[key]; } } });};转换字节单位
export function bytesToSize(size) { if (size < 0.1 * 1024) { //小于0.1KB,则转化成B size = size.toFixed(2) + "B"; } else if (size < 0.1 * 1024 * 1024) { // 小于0.1MB,则转化成KB size = (size / 1024).toFixed(2) + "KB"; } else if (size < 0.1 * 1024 * 1024 * 1024) { // 小于0.1GB,则转化成MB size = (size / (1024 * 1024)).toFixed(2) + "MB"; } else { // 其他转化成GB size = (size / (1024 * 1024 * 1024)).toFixed(2) + "GB"; } return size;}所有国家列表/国家旗帜
// https://github.com/benkeen/country-region-data.gitimport CountryRegionData from 'country-region-data/data.json';const countryShortCodeObj = {};
const option = CountryRegionData.map(country => { const { countryName, regions, countryShortCode } = country; const children = regions.map(rg => { const { name: label } = rg; return { label, value: label } }) countryShortCodeObj[countryName] = countryShortCode; return { label: countryName, value: countryName, children }})
export { countryShortCodeObj }export default option;
// 获取国家旗帜[CN](https://purecatamphetamine.github.io/country-flag-icons/3x2/CN.svg)对 localStorage 进行封装
const ls = { getItem(key: string) { let data = window.localStorage.getItem(key); if (data) { try { return JSON.parse(data); } catch (e) { console.error(e); } } }, setItem(key: string, value: any) { try { window.localStorage.setItem(key, JSON.stringify(value)); } catch (e) { console.error(e); } }, removeItem(key: string) { window.localStorage.removeItem(key); },};export default ls;一些常用的正则表达式
// 中文export const chinese = /^[\u0391-\uFFE5]+$/;// 手机号export const mobile = /^[0-9]\d{3,9}$/;// 座机export const landline = /^((0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/;// 邮箱export const email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;// 网址export const url = /^((http|ftp|https):\/\/)(([a-zA-Z0-9._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(\/[a-zA-Z0-9&%_./-~-]*)?/;//禁止输入空格export const blank = /^[^\s]*$/;export const number = /^\d+$/;
//禁止只输入空格export const onlyBlank = /^([\s\S]*\S).*$/;
export const password = /^.*(?=.*[0-9])(?=.*[a-zA-Z])\w{8,20}/;
// 特殊字符export const specialReg = /[`~!#$%^&*()_\\+=<>?:/"{}|~!#¥%……&*()={}|《》?:“”【】、;;',.‘’,。、\s+]/g;// 日期格式传入日期+时间时校验也可通过export const date = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])(\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d)*$/;export const dateTime = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
// urlexport const isUrl = (str: string) => /^((http|ftp|https):\/\/)(([a-zA-Z0-9._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(\/[a-zA-Z0-9&%_./-~-]*)?/.test( str );复制功能
export function copy(text: string) { const input = document.createElement("textarea"); input.value = text; input.style.position = "fixed"; input.style.left = "-9999px"; document.body.append(input); input.select(); document.execCommand("Copy"); document.body.removeChild(input);}移动端判断
/* 判断pc移动端 */export function IsMobile() { var userAgentInfo = navigator.userAgent; var Agents = [ "Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod", ]; var flag = false; for (var v = 0; v < Agents.length; v++) { if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = true; break; } } return flag;}字符串操作
/** * 获取字符串长度,英文字符 长度1,中文字符长度2 * @param {*} str */export const getStrFullLength = (str = "") => str.split("").reduce((pre, cur) => { const charCode = cur.charCodeAt(0); if (charCode >= 0 && charCode <= 128) { return pre + 1; } return pre + 2; }, 0);/** * 获取字符串宽度 * @param {*} str */export const textSize = (fontSize, fontFamily, text) => { var span = document.createElement("span"); var result = {}; result.width = span.offsetWidth; result.height = span.offsetHeight; span.style.visibility = "hidden"; span.style.fontSize = fontSize; span.style.fontFamily = fontFamily; span.style.display = "inline-block"; document.body.appendChild(span); if (typeof span.textContent !== "undefined") { span.textContent = text; } else { span.innerText = text; } result.width = parseFloat(window.getComputedStyle(span).width) - result.width; result.height = parseFloat(window.getComputedStyle(span).height) - result.height; return result;};
/** 字符串前后补0操作 */"123".padStart(5, 0); // 00123"123".padEnd(4, 0); // 1230
/** 生成随机ID */const randomId = (len) => Math.random().toString(36).substr(3, len);const id = randomId(10);
/** 生成随机HEX色值 */const randomColor = () => "#" + Math.floor(Math.random() * 0xffffff) .toString(16) .padEnd(6, "0");const color = randomColor();Number 操作
/** 精确小数位 */const RoundNum = (num, decimal) => Math.round(num * 10 ** decimal) / 10 ** decimal;const num = RoundNum(1.69, 1);
/** 生成随机数 */const RandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;const num = RandomNum(12, 122);获取 URL 查询参数
const params = new URLSearchParams(location.search.replace(/\?/gi, "")); // location.search = /book?id=6850413616484040711"params.has("id"); // trueparams.get("id"); // "6850413616484040711"数组操作
// 创建长度为7的数组Array.from({ length: 7 }); //[undefined, undefined, undefined, undefined, undefined, undefined, undefined]
// 创建长度为3的数组 并向其中插入0const length = 3;const init = 0;const result = Array.from({ length }, () => init); // [0,0,0]const arr = new Array(length).fill(0); // [0,0,0]
// Array.from的第二个参数,可以遍历数组 相当于maplet b = [1, 2, 3];console.log(Array.from(b, (v) => v + 2)); // [3,4,5]
/** * 求数组差集 */export const subSet = function (arr1, arr2) { let set1 = new Set(arr1); let set2 = new Set(arr2); let subset = []; for (let item of set1) { if (!set2.has(item)) { subset.push(item); } } return subset;};
/** * 数组解构赋值 */const a = [1, 2, 3, 4];const [b, c, ...d] = a;b; // 1c; // 2d; // [3,4]// 也可以使用对象的方式解构 key对应下标 可以直接获取数组lengthconst { 0: b, length, [length - 1]: last } = arr;b; // 1last; // 4length; // 4
/** * 数组克隆 */const clone = (arr) => arr.slice(0);const clone = (arr) => [...arr];const clone = (arr) => Array.from(arr);const clone = (arr) => arr.map((x) => x);const clone = (arr) => arr.concat([]);const clone = (arr) => JSON.parse(JSON.stringify(arr));数字千分位
/** * 数字加, */export const formatNumber = function (n) { var b = parseInt(n).toString() var len = b.length if (len <= 3) { return b } var r = len % 3 return r > 0 ? b.slice(0, r) + ',' + b.slice(r, len).match(/\d{3}/g).join(',') : b.slice(r, len).match(/\d{3}/g).join(',')}
(v) => ${v}.replace(/\d{1,3}(?=(\d{3})+$)/g, (s) => ${s},)
export const thousandNum = num => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");const money = thousandNum(2548745.45); // '2,548,745.45'获取随机颜色
const getRandomColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`;文件下载
/** * 文件下载 * @param {Object} url */export async function downLoadFile(url, name) { const response = await service({ method: "get", url, responseType: "arraybuffer", }); // 内容转变成blob地址 const blob = await new Blob([response.data], { type: "application/vnd.ms-excel", }); // 创建隐藏的可下载链接 const objectUrl = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = objectUrl; name && (a.download = name); document.body.appendChild(a); a.click(); setTimeout(() => document.body.removeChild(a), 1000);}格式化时间yyyy-MM-DD HH:mm
const formatTime = (date) => { const d = new Date(new Date(date).getTime() + 8 * 3600 * 1000); const dateTimeArr = new Date(d) .toISOString() .split(/[^0-9]/) .slice(0, -2); const dateArr = dateTimeArr.slice(0, 3); const timeArr = dateTimeArr.slice(3); return `${dateArr.join("-")} ${timeArr.join(":")}`;};console.log(formatTime(new Date())); javascript工具类函数
https://wangxiang.website/posts/语言基础/javascript-utils/