UNPKG

@ivujs/i-utils

Version:

前端模块化 JavaScript 工具库

1,793 lines (1,781 loc) 299 kB
/*! * @ivujs/i-utils v2.1.8 * Copyright 2021-2026, <gao911222@163.com> * Released under the MIT License. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.iUtils = {})); })(this, (function (exports) { 'use strict'; /** * 排序相关常量配置(全局只读) * * DESC: 降序 * - 取值:0 * * ASC: 升序 * - 取值:1 * * RANDOM: 随机排序 * - 取值:2 */ const SORT = { // 降序 DESC: 0, // 升序 ASC: 1, // 随机排序 RANDOM: 2, }; /** * 数学计算相关常量配置(全局只读) * * ROUND: 正常四舍五入 * - 取值:0 * - 示例:1.354保留两位是1.35;1.355保留两位是1.36 * * ROUND_FLOOR: 向下舍出 * - 取值:1 * - 示例:1.354保留两位是1.35;1.355保留两位是1.35 */ const MATH = { // 正常四舍五入,如:1.354保留两位是1.35;1.355保留两位是1.36; ROUND: 0, // 向下舍出,如:1.354保留两位是1.35;1.355保留两位是1.35; ROUND_FLOOR: 1, }; /** * 语言相关常量配置(全局只读) * * ZH: 中文 * - zh * * EN: 英文 * - en */ const LANG = { // 中文 ZH: "zh", // 英文 EN: "en", }; /** * 正则表达式相关常量配置(全局只读) * * CH: 中文汉字 * EN: 英文字母 * LOWER_CASE: 小写字母 * UPPER_CASE: 大写字母 * CH_NAME: 中文姓名(2-16位) * EN_NAME: 英文姓名(1-20位) * NUMBER: 数字(包含正数和负数) * INTEGER: 整数(包含:0,正整数和负整数) * DECIMAL: 小数(包含正小数和负小数) * INT_OR_FLOAT: 正整数或者保留两位小数 * MOBILE: 手机号码(支持+86) * PHONE: 固定电话号码(比如:0755-1111111) * EMAIL: 邮箱 * ID_CARD: 一代15位或二代18位身份证 * ID_CARD15: 仅校验一代15位身份证 * ID_CARD18: 仅校验二代18位身份证 * BANK_CARD: 银行卡号 * POST_CODE: 邮政编码 * URL: url地址(可获取主机地址、主机名、端口号、协议、查询参数、hash等信息) * IP: ip地址 * IP6: IPv6地址 * EXTERNAL: 外链(http、https、mail、tel电话) */ const REGEXP = { // 中文汉字 CH: /^[\u4E00-\u9FA5]+$/, // 英文字母,1个以上 EN: /^[a-zA-Z]+$/, // 小写字母 LOWER_CASE: /^[a-z]+$/, // 大写字母 UPPER_CASE: /^[A-Z]+$/, // 中文姓名,2-16位(支持少数民族姓名间隔符「·」) CH_NAME: /^[\u4e00-\u9fa5·]{2,16}$/, // 英文姓名,1-20位 EN_NAME: /^[a-zA-Z\s]{1,20}$/, // 数字,包含正数和负数 NUMBER: /^([-+])?\d+(\.\d+)?$/, // 整数,包含:0,正整数和负整数 INTEGER: /^(0|[1-9][0-9]*|-[1-9][0-9]*)$/, // 小数,包含正小数和负小数 DECIMAL: /^([-+])?\d+\.\d+$/, // 正整数或者保留两位小数 INT_OR_FLOAT: /(^[1-9][0-9]*$)|(^[1-9][0-9]*\.[0-9]{1,2}$)|(^0\.[0-9]{1,2}$)|(^0$)/, // 手机号码,支持+86 MOBILE: /^(?:(?:\+|00)86)?1[1-9]\d{9}$/, // 固定电话号码,比如:0755-1111111 PHONE: /^(?:(?:\d{3}-)?\d{8}|^(?:\d{4}-)?\d{7,8})(?:-\d+)?$/, // 邮箱 EMAIL: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/, // 一代15位或二代18位身份证 ID_CARD: /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/, // 仅校验一代15位身份证 ID_CARD15: /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)/, // 仅校验二代18位身份证 ID_CARD18: /(^\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/, // 银行卡号 BANK_CARD: /^[1-9]\d{9,29}$/, // 邮政编码 POST_CODE: /^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\d{4}$/, // url地址,可以获取到主机地址、主机名、端口号、协议、查询参数、hash等信息c URL: /^(?:(ftp|https?|ftps):\/\/)?((?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+(?:[a-zA-Z]{2,6})?)?(?::(\d+))?(?:\/([^\?#]*))?(?:\?([^#]*))?(?:#(.*))?$/, // ip地址 IP: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, // IPv6地址 IP6: /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|::([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}|[0-9a-fA-F]{1,4}::([0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4})$/i, // 是外链,http,https,mail,tel电话 EXTERNAL: /^(http:|https:|ftp:|ftps:|mailto:|tel:)/i, }; /** * 日期相关的多语言常量配置(全局只读) * * AM_PM: 上午/下午多语言配置 * - zh: { AM: "上午", PM: "下午" } * - en: { AM: "AM", PM: "PM" } * * WEEK: 星期多语言配置 * - zh.FULL: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"] * - zh.SHORT: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] * - zh.MINI: ["日", "一", "二", "三", "四", "五", "六"] * - en.FULL: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] * - en.SHORT: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] * - en.MINI: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"] * * MONTH: 月份多语言配置 * - zh.FULL: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] * - zh.SHORT: ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"] * - en.FULL: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] * - en.SHORT: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] * * QUARTER: 季度多语言配置 * - zh.FULL: ["第一季度", "第二季度", "第三季度", "第四季度"] * - zh.SHORT: ["一季度", "二季度", "三季度", "四季度"] * - zh.MINI: ["一", "二", "三", "四"] * - en.FULL: ["quarter 1st", "quarter 2nd", "quarter 3rd", "quarter 4th"] * - en.SHORT: ["Q1th", "Q2nd", "Q3rd", "Q4th"] * - en.MINI: ["Q1", "Q2", "Q3", "Q4"] * * OVER_TIME: 剩余时间单位多语言配置 * - zh: { YEAR: "年", MONTH: "月", DATE: "日", HOUR: "时", MINUTE: "分", SECOND: "秒", MILLISECOND: "毫秒", DAY: "天", QUARTER: "季度" } * - en: { YEAR: "year", MONTH: "month", DATE: "date", HOUR: "hour", MINUTE: "minute", SECOND: "second", MILLISECOND: "millisecond", DAY: "day", QUARTER: "quarter" } * * PASS_TIME: 过去时间描述多语言配置 * - zh: { YEAR: "年前", MONTH: "个月前", DAY: "天前", BEFORE_YESTERDAY: "前天", YESTERDAY: "昨天", TODAY: "今天", HOUR: "小时前", MINUTE: "分钟前", JUST: "刚刚" } * - en: { YEAR: " year ago", MONTH: " month ago", DAY: " day ago", BEFORE_YESTERDAY: "before yesterday", YESTERDAY: " yesterday", TODAY: " today", HOUR: " hour ago", MINUTE: " minute ago", JUST: " just" } * * HOLIDAY: 节假日多语言配置 * - zh: ["元旦", "春节", "清明节", "劳动节", "端午节", "中秋节", "国庆节"] * - en: ["New Year‘s Day", "Spring Festival", "Tomb Sweeping Day", "Labor Day", "Dragon Boat Festival", "Mid-Autumn Day", "National Day"] * * ZODIAC: 星座多语言配置 * - zh: ["摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座"] * - en: ["Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius"] * * CHINESE_ZODIAC: 生肖多语言配置 * - zh: ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"] * - en: ["Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig"] * * HEAVENLY_STEMS: 天干多语言配置 * - zh: ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"] * - en: ["Jia", "Yi", "Bing", "Ding", "Wu", "Ji", "Geng", "Xin", "Ren", "Gui"] * * EARTHLY_BRANCHES: 地支多语言配置 * - zh: ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"] * - en: ["Zi", "Chou", "Yin", "Mao", "Chen", "Si", "Wu", "Wei", "Shen", "You", "Xu", "Hai"] */ const DATE = { // 上午和下午 AM_PM: { zh: { AM: "上午", PM: "下午", }, en: { AM: "AM", PM: "PM", }, }, // 周 WEEK: { zh: { FULL: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], SHORT: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], MINI: ["日", "一", "二", "三", "四", "五", "六"], }, en: { FULL: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], SHORT: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], MINI: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], }, }, // 月 MONTH: { zh: { FULL: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], SHORT: ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"], }, en: { FULL: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ], SHORT: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], }, }, // 季度 QUARTER: { zh: { FULL: ["第一季度", "第二季度", "第三季度", "第四季度"], SHORT: ["一季度", "二季度", "三季度", "四季度"], MINI: ["一", "二", "三", "四"], }, en: { FULL: ["quarter 1st", "quarter 2nd", "quarter 3rd", "quarter 4th"], SHORT: ["Q1th", "Q2nd", "Q3rd", "Q4th"], MINI: ["Q1", "Q2", "Q3", "Q4"], }, }, // 已过日期类型 OVER_TIME: { zh: { YEAR: "年", MONTH: "月", DATE: "日", HOUR: "时", MINUTE: "分", SECOND: "秒", MILLISECOND: "毫秒", DAY: "天", QUARTER: "季度", }, en: { YEAR: "year", MONTH: "month", DATE: "date", HOUR: "hour", MINUTE: "minute", SECOND: "second", MILLISECOND: "millisecond", DAY: "day", QUARTER: "quarter", }, }, // 时间节点 PASS_TIME: { zh: { YEAR: "年前", MONTH: "个月前", DAY: "天前", BEFORE_YESTERDAY: "前天", YESTERDAY: "昨天", TODAY: "今天", HOUR: "小时前", MINUTE: "分钟前", JUST: "刚刚", }, en: { YEAR: " year ago", MONTH: " month ago", DAY: " day ago", BEFORE_YESTERDAY: "before yesterday", YESTERDAY: " yesterday", TODAY: " today", HOUR: " hour ago", MINUTE: " minute ago", JUST: " just", }, }, // 节假日 HOLIDAY: { zh: ["元旦", "春节", "清明节", "劳动节", "端午节", "中秋节", "国庆节"], en: [ "New Year‘s Day", "Spring Festival", "Tomb Sweeping Day", "Labor Day", "Dragon Boat Festival", "Mid-Autumn Day", "National Day", ], }, // 星座 ZODIAC: { zh: [ "摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", ], en: [ "Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", ], }, // 生肖 CHINESE_ZODIAC: { zh: ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"], en: ["Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig"], }, // 天干地支 HEAVENLY_STEMS: { zh: ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"], en: ["Jia", "Yi", "Bing", "Ding", "Wu", "Ji", "Geng", "Xin", "Ren", "Gui"], }, EARTHLY_BRANCHES: { zh: ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"], en: ["Zi", "Chou", "Yin", "Mao", "Chen", "Si", "Wu", "Wei", "Shen", "You", "Xu", "Hai"], }, }; /** * 键盘码相关常量配置(全局只读) * * 字符键: * - 8: Backspace * - 9: Tab * - 13: Enter * - 16: Shift * - 17: Ctrl * - 18: Alt * - 19: Pause * - 20: Caps Lock * - 27: Escape * - 32: Space * - 33: Page Up * - 34: Page Down * - 35: End * - 36: Home * - 37: Left * - 38: Up * - 39: Right * - 40: Down * - 42: Print Screen * - 45: Insert * - 46: Delete * * 数字键: * - 48: 0 * - 49: 1 * - 50: 2 * - 51: 3 * - 52: 4 * - 53: 5 * - 54: 6 * - 55: 7 * - 56: 8 * - 57: 9 * * 字母键: * - 65: A * - 66: B * - 67: C * - 68: D * - 69: E * - 70: F * - 71: G * - 72: H * - 73: I * - 74: J * - 75: K * - 76: L * - 77: M * - 78: N * - 79: O * - 80: P * - 81: Q * - 82: R * - 83: S * - 84: T * - 85: U * - 86: V * - 87: W * - 88: X * - 89: Y * - 90: Z * * window 相关键: * - 91: Windows * - 93: Right Click * * 数字小键盘(Numpad): * - 96: Numpad 0 * - 97: Numpad 1 * - 98: Numpad 2 * - 99: Numpad 3 * - 100: Numpad 4 * - 101: Numpad 5 * - 102: Numpad 6 * - 103: Numpad 7 * - 104: Numpad 8 * - 105: Numpad 9 * - 106: Numpad * * - 107: Numpad + * - 109: Numpad - * - 110: Numpad . * - 111: Numpad / * * F功能键: * - 112: F1 * - 113: F2 * - 114: F3 * - 115: F4 * - 116: F5 * - 117: F6 * - 118: F7 * - 119: F8 * - 120: F9 * - 121: F10 * - 122: F11 * - 123: F12 * * 特殊符号/功能键: * - 144: Num Lock * - 145: Scroll Lock * - 182: My Computer * - 183: My Calculator * - 186: ; * - 187: = * - 188: , * - 189: - * - 190: . * - 191: / * - 192: ` * - 219: [ * - 220: \ * - 221: ] * - 222: ' */ const KEYCODE = { // 字符键 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", 19: "Pause", 20: "Caps Lock", 27: "Escape", 32: "Space", 33: "Page Up", 34: "Page Down", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 42: "Print Screen", 45: "Insert", 46: "Delete", // 数字键 48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9", // 字母键 65: "A", 66: "B", 67: "C", 68: "D", 69: "E", 70: "F", 71: "G", 72: "H", 73: "I", 74: "J", 75: "K", 76: "L", 77: "M", 78: "N", 79: "O", 80: "P", 81: "Q", 82: "R", 83: "S", 84: "T", 85: "U", 86: "V", 87: "W", 88: "X", 89: "Y", 90: "Z", // window 91: "Windows", 93: "Right Click", // Numpad 96: "Numpad 0", 97: "Numpad 1", 98: "Numpad 2", 99: "Numpad 3", 100: "Numpad 4", 101: "Numpad 5", 102: "Numpad 6", 103: "Numpad 7", 104: "Numpad 8", 105: "Numpad 9", 106: "Numpad *", 107: "Numpad +", 109: "Numpad -", 110: "Numpad .", 111: "Numpad /", // F功能键 112: "F1", 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", // 特殊符号 144: "Num Lock", 145: "Scroll Lock", 182: "My Computer", 183: "My Calculator", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", }; /** * 身份证号相关常量配置(全局只读) * * PROVINCE: 身份证号前两位对应的省份/地区编码映射 * - 11: 北京 * - 12: 天津 * - 13: 河北 * - 14: 山西 * - 15: 内蒙古 * - 21: 辽宁 * - 22: 吉林 * - 23: 黑龙江 * - 31: 上海 * - 32: 江苏 * - 33: 浙江 * - 34: 安徽 * - 35: 福建 * - 36: 江西 * - 37: 山东 * - 41: 河南 * - 42: 湖北 * - 43: 湖南 * - 44: 广东 * - 45: 广西 * - 46: 海南 * - 50: 重庆 * - 51: 四川 * - 52: 贵州 * - 53: 云南 * - 54: 西藏 * - 61: 陕西 * - 62: 甘肃 * - 63: 青海 * - 64: 宁夏 * - 65: 新疆 * - 71: 台湾 * - 81: 香港 * - 82: 澳门 * - 91: 国外 * * SEX: 身份证号解析的性别映射 * - MAN: 男 * - WOMAN: 女 */ const ID_CARD = { // 身份证号对应的省 PROVINCE: { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外", }, // 性别 SEX: { MAN: "男", WOMAN: "女", }, }; /** * @module 校验 */ /** * 判断是整数 * @param {*} value 参数 * @returns {boolean} result 返回结果 */ function isInteger(value) { return Number.isInteger(value); } /** * 判断是小数 * @param {*} value 参数 * @returns {boolean} result 返回结果 */ function isDecimal(value) { return /^\d+\.\d+$/.test(value); } /** * 判断类型是数字 Number * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isNumber(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Number"; } /** * 判断类型是字符串 String * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isString(value) { return Object.prototype.toString.call(value).slice(8, -1) === "String"; } /** * 判断类型是数组 Array * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isArray(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Array"; } /** * 判断类型是对象 Object * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isObject(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Object"; } /** * 判断类型是布尔 boolean * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isBoolean(value) { return Object.prototype.toString.call(value).slice(8, -1) === "boolean"; } /** * 判断类型是日期 Date * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isDate(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Date"; } /** * 判断类型是函数 Function * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isFunction(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Function"; } /** * 判断类型是函数字符串 FunctionString * @description 支持普通函数,异步函数,箭头函数 * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isFunctionString(value) { if (value) { try { const fn = new Function(`return ${value}`)(); return typeof fn === "function"; } catch (e) { // 如果发生错误,比如语法错误,那么这不是一个有效的函数 return false; } } else { return false; } } /** * 判断类型是异步函数 AsyncFunction * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isAsyncFunction(value) { return Object.prototype.toString.call(value).slice(8, -1) === "AsyncFunction"; } /** * 判断类型是 Symbol * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isSymbol(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Symbol"; } /** * 判断类型是正则 RegExp * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isRegExp(value) { return Object.prototype.toString.call(value).slice(8, -1) === "RegExp"; } /** * 判断类型是错误 Error * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isError(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Error"; } /** * 判断类型是 Promise * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isPromise(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Promise"; } /** *判断类型是 Map * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isMap(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Map"; } /** * 判断类型是 WeakMap * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isWeakMap(value) { return Object.prototype.toString.call(value).slice(8, -1) === "WeakMap"; } /** * 判断类型是 Set * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isSet(value) { return Object.prototype.toString.call(value).slice(8, -1) === "Set"; } /** * 判断类型是 WeakSet * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isWeakSet(value) { return Object.prototype.toString.call(value).slice(8, -1) === "WeakSet"; } /** * 判断类型是 BigInt * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isBigInt(value) { return Object.prototype.toString.call(value).slice(8, -1) === "BigInt"; } /** * 判断类型是 Json * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isJson(value) { try { JSON.parse(value); return true; } catch (error) { return false; } } /* 数据值校验 */ /** * 判断值为真 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isTrue(value) { return !isFalse(value); } /** * 判断值为假 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isFalse(value) { return (value === undefined || value === null || value === "undefined" || value === "null" || value === 0 || value === false || isNaN(value)); } /** * 判断非数字 * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isNaN(value) { return (value == null || typeof value === "boolean" || Array.isArray(value) || value === "" || Number.isNaN(Number(value))); } /** * 判断是数字 * @description 等同于isNumber() * @param {*} value 参数 * @returns {boolean} 返回结果 */ function isNotNaN(value) { return !isNaN(value); } /** * 判断对象为空 * @description 判断值是否为空,如果对象初始化了值则不为空 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isNull(value) { return value === undefined || value === null || value === ""; } /** * 判断对象不为空 * @description 判断值是否为空,如果对象初始化了值则不为空 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isNotNull(value) { return !isNull(value); } /** * 判断值为空 * @description 判断是否是有意义不为空的值,如果值是{},[]空的数据则为空 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isEmpty(value) { if (isNull(value)) return true; if (typeof value === "string" || Array.isArray(value)) { return value.length === 0; } if (typeof value === "object") { if (value instanceof Map || value instanceof Set) { return value.size === 0; } if (value instanceof Date || value instanceof RegExp || value instanceof Error) { return false; } return Object.keys(value).length === 0; } return false; } /** * 判断值不为空 * @description 判断是否是有意义不为空的值,如果值是{},[]空的数据则为空 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isNotEmpty(value) { return !isEmpty(value); } /** * 判断值是空白的 * @description 同时会校验空值,空对象,以及空白符号 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isBlank(value) { return isEmpty(value) || /^\s*$/.test(value); } /** * 判断值不是空白的 * @description 同时会校验空值,空对象,以及空白符号 * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isNotBlank(value) { return !isBlank(value); } /** * 判断值是undefined * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isUndefined(value) { return value === undefined; } /** * 判断值不是undefined * @param {*} value 校验的参数 * @returns {boolean} 返回结果 */ function isNotUndefined(value) { return !isUndefined(value); } /* 数据比较 */ /** * 判断两个值是否相等 * @param {*} value1 参数1 * @param {*} value2 参数2 * @returns {boolean} 返回结果 */ function equals(value1, value2) { return Object.is(value1, value2); } /** * 判断两个值是否相等(忽略大小写) * @param {*} value1 参数1 * @param {*} value2 参数2 * @returns {boolean} 返回结果 */ function equalsIgnoreCase(value1, value2) { return Object.is(value1.toLowerCase(), value2.toLowerCase()); } /** * 深度对比数据 * @description 可以对比任意数据,对象、数组、日期等也可深度对比,对象不区分先后顺序 * @param {*} x 数据1 * @param {*} args 数据2 * @returns {boolean} 返回对比结果 */ function deepCompare(x, ...args) { let leftChain = []; let rightChain = []; // 核心对比函数(添加严格类型标注) const compare2Objects = (xObj, yObj) => { // 1. 处理 NaN 特殊场景(NaN === NaN 返回 false,需单独判断) if (Number.isNaN(xObj) && Number.isNaN(yObj)) { return true; } // 2. 原始类型/引用同一对象 直接对比 if (xObj === yObj) { return true; } // 3. 特殊内置对象对比(函数/日期/正则/包装对象) const typeOfX = typeof xObj; const typeOfY = typeof yObj; // 函数对比:通过 toString 比较内容 if (typeOfX === "function" && typeOfY === "function") { return xObj.toString() === yObj.toString(); } // 日期对象对比:时间戳一致则相等 if (xObj instanceof Date && yObj instanceof Date) { return xObj.getTime() === yObj.getTime(); } // 正则对象对比:源文本+标志位一致则相等 if (xObj instanceof RegExp && yObj instanceof RegExp) { return xObj.source === yObj.source && xObj.flags === yObj.flags; } // 字符串/数字包装对象对比 if ((xObj instanceof String && yObj instanceof String) || (xObj instanceof Number && yObj instanceof Number)) { return xObj.toString() === yObj.toString(); } // 4. 非对象类型(排除上述特殊类型后)直接返回 false if (!(xObj instanceof Object && yObj instanceof Object)) { return false; } // 5. 原型链/构造函数校验 if (xObj.isPrototypeOf(yObj) || yObj.isPrototypeOf(xObj)) { return false; } if (xObj.constructor !== yObj.constructor) { return false; } if (xObj.prototype !== yObj.prototype) { return false; } // 6. 循环引用检测(避免无限递归) if (leftChain.includes(xObj) || rightChain.includes(yObj)) { return false; } // 7. 遍历对象属性,对比键存在性和类型 const xObjKeys = Object.keys(xObj); const yObjKeys = Object.keys(yObj); // 先对比属性数量(数量不同直接不相等) if (xObjKeys.length !== yObjKeys.length) { return false; } // 遍历所有属性,校验存在性、类型、值 for (const p of yObjKeys) { if (Object.prototype.hasOwnProperty.call(xObj, p) !== Object.prototype.hasOwnProperty.call(yObj, p)) { return false; } const xProp = xObj[p]; const yProp = yObj[p]; if (typeof xProp !== typeof yProp) { return false; } } // 深度对比属性值 for (const p of xObjKeys) { const xProp = xObj[p]; const yProp = yObj[p]; if (typeof xProp === "object" || typeof xProp === "function") { leftChain.push(xObj); rightChain.push(yObj); if (!compare2Objects(xProp, yProp)) { return false; } leftChain.pop(); rightChain.pop(); } else { if (xProp !== yProp) { return false; } } } return true; }; // 边界处理:参数数量不足时的兜底 if (arguments.length < 2) { console.warn("deepCompare 需要至少两个对比参数"); return true; } // 遍历所有传入的参数(支持对比多个值) for (const y of args) { leftChain = []; rightChain = []; if (!compare2Objects(x, y)) { return false; } } return true; } /** * @module 字符串 */ /* 字符串处理 */ /** * 字符串中是否包含指定的元素 * @param {string} value 包含的元素 * @param {string} str 查找的字符串 * @returns {boolean} 返回true和false */ function inString(value, str) { return str.includes(value); } /** * 去除字符串前后位置空格 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function trim(value) { return value.replace(/(^\s*)|(\s*$)/g, ""); } /** * 去除字符串开始位置的空格 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function trimStart(value) { return value.replace(/(^\s*)/g, ""); } /** * 去除字符串结束位置的空格 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function trimEnd(value) { return value.replace(/(\s*$)/g, ""); } /** * 去除字符串中全部的空格 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function trimAll(value) { return value.replace(/\s+/g, ""); } /** * 替换所有指定字符串为新的字符串 * @param {string} value 参数 * @param {string} oldSubstr 需要替换的字符串 * @param {string} newSubstr 替换后的字符串 * @returns {string} 返回处理后的字符串 */ function replaceAll(value, oldSubstr, newSubstr) { return value.replace(new RegExp(oldSubstr, "gm"), newSubstr); } /* 字符串转换 */ /** * 字符串转大写 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toUpperCase(value) { return String(value).toLocaleUpperCase(); } /** * 字符串转小写 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toLowerCase(value) { return String(value).toLocaleLowerCase(); } /** * 转为 snake_case 下划线命名 * @description 支持 驼峰命名,短横命名,帕斯卡命名 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toSnakeCase(value) { // 驼峰 if (/^[a-z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { return value.replace(/([A-Z])/g, "_$1").toLowerCase(); } // 短横 else if (value.indexOf("-") > 0) { return value.replace(/-/g, "_").toLowerCase(); } // 帕斯卡 else if (/^[A-Z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { value = value.charAt(0).toLowerCase() + value.slice(1); return value.replace(/([A-Z])/g, "_$1").toLowerCase(); } // 不符合格式 else { throw new TypeError(`toSnakeCase: value should be a string`); } } /** * 转为 kebab-case 短横命名 * @description 支持 下划线,驼峰命名,帕斯卡命名 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toKebabCase(value) { // 下划线 if (value.indexOf("_") > 0) { return value.replace(/_/g, "-").toLowerCase(); } // 驼峰 else if (/^[a-z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { return value.replace(/([A-Z])/g, "-$1").toLowerCase(); } // 帕斯卡 else if (/^[A-Z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { const newStr = value.charAt(0).toLowerCase() + value.slice(1); return newStr.replace(/([A-Z])/g, "-$1").toLowerCase(); } // 不符合格式 else { throw new TypeError("toKebabCase: value should be a string"); } } /** * 转为 camelCase 驼峰命名 * @description 支持 下划线命名,短横命名,帕斯卡命名 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toCamelCase(value) { // 下划线 if (value.indexOf("_") > 0) { return value.replace(/\_(\w)/g, function (all, letter) { return letter.toUpperCase(); }); } // 短横 else if (value.indexOf("-") > 0) { return value.replace(/\-(\w)/g, function (all, letter) { return letter.toUpperCase(); }); } // 帕斯卡 else if (/^[A-Z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { return value.charAt(0).toLowerCase() + value.slice(1); } // 不符合格式 else { throw new TypeError("toCamelCase: value should be a string"); } } /** * 转为 PascalCase 帕斯卡命名 * @description 支持 下划线命名,短横命名,驼峰命名 * @param {string} value 参数 * @returns {string} 返回处理后的字符串 */ function toPascalCase(value) { // 下划线 if (value.indexOf("_") > 0) { const newStr = value.replace(/\_(\w)/g, function (all, letter) { return letter.toUpperCase(); }); return newStr.charAt(0).toUpperCase() + newStr.slice(1); } // 短横 else if (value.indexOf("-") > 0) { const newStr = value.replace(/\-(\w)/g, function (all, letter) { return letter.toUpperCase(); }); return newStr.charAt(0).toUpperCase() + newStr.slice(1); } // 驼峰 else if (/^[a-z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { return value.charAt(0).toUpperCase() + value.slice(1); } // 不符合格式 else { throw new TypeError("toPascalCase: value should be a string"); } } /* 字符串格式化 */ /** * 数字前补齐0达到指定位数 * @description 相当于原生的 padStart(2,'0') * @param {number|string} value 补零的数字 * @param {number} maxLength 补齐0后的最大长度,默认2位 * @returns {string} 返回补0后指定位数的字符串 */ function padZeroStart(value, maxLength = 2) { value = String(value).trim(); if (maxLength < 0) { throw new TypeError("padZeroStart: maxLength should be greater than 0"); } if (isNull(value) || isNaN(value)) { throw new TypeError("padZeroStart: value must be a valid number or numeric string"); } // 前面补0 let len = value.toString().length; while (len < maxLength) { value = "0" + value; len++; } return value; } /** * 数字后补齐0达到指定位数 * @description 相当于原生的 padEnd(2,'0') * @param {number|string} value 补零的数字 * @param {number} maxLength 补齐0后的最大长度,默认2位 * @returns {string} 返回补0后指定位数的字符串 */ function padZeroEnd(value, maxLength = 2) { value = String(value).trim(); if (maxLength < 0) { throw new TypeError("padZeroEnd: maxLength should be greater than 0"); } if (isNull(value) || isNaN(value)) { throw new TypeError("padZeroEnd: value must be a valid number or numeric string"); } // 后面补0 let len = value.toString().length; while (len < maxLength) { value = value + "0"; len++; } return value; } /** * 格式化为标题样式 * @param {string} value 字符串值 * @returns {string} 返回格式化后的标题样式 */ function formatTitle(value) { if (!value) return ""; return value .split(/(?=[A-Z])|[\.\-\s_]/) .map((s) => s.trim()) .filter((s) => !!s) .map((s) => toPascalCase(s.toLowerCase())) .join(" "); } /** * 格式化字符串模版 * @param {string} value 字符串值 * @param {Object} data 模版数据 * @returns {string} 返回格式化后的模版字符串 */ function formatTemplate(value, data) { if (!value) return ""; return Array.from(value.matchAll(/\{\{(.+?)\}\}/g)).reduce((acc, match) => { return acc.replace(match[0], data[match[1]]); }, value); } /** * 格式化千分位数字 * @description 支持任意数据传参,如果非数字则不会格式化,并返回原数据 * @param {number|string} num 数字 * @returns {string} 返回格式化后的千分位数字 */ function formatThousand(num) { if (!parseFloat(String(num))) return String(num); num = String(num); const regex = num.indexOf(".") > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(?:\d{3})+$)/g; return num.replace(regex, "$1,"); } /** * 格式化人民币金额大写 * @param {number|string} money 金额 * @returns {string} 返回金额大写 */ function formatRmbChinese(money) { // 汉字的数字 const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]; // 基本单位 const cnIntRadiance = ["", "拾", "佰", "仟"]; // 对应整数部分扩展单位 const cnIntUnits = ["", "万", "亿", "兆"]; // 对应小数部分单位 const cnDecUnits = ["角", "分", "毫", "厘"]; // 整数金额时后面跟的字符 const cnInteger = "整"; // 整型完以后的单位 const cnIntLast = "元"; // 最大处理的数字 const maxNum = Number("999999999999999.9999"); // 金额整数部分 let integerNum; // 金额小数部分 let decimalNum; // 输出的中文金额字符串 let chineseStr = ""; // 分离金额后用的数组,预定义 let parts; if (money === "") { // 不能用== return ""; } money = parseFloat(String(money)); if (money >= maxNum) { // 超出最大处理数字,抛出异常 throw new TypeError("formatRmbChinese: calculated number overflow"); } if (money === 0) { chineseStr = cnNums[0] + cnIntLast + cnInteger; return chineseStr; } // 转换为字符串 money = money.toString(); if (money.indexOf(".") === -1) { integerNum = money; decimalNum = ""; } else { parts = money.split("."); integerNum = parts[0]; decimalNum = parts[1].substr(0, 4); } // 获取整型部分转换 if (parseInt(integerNum, 10) > 0) { let zeroCount = 0; const IntLen = integerNum.length; for (let i = 0; i < IntLen; i++) { const n = integerNum.substr(i, 1); const p = IntLen - i - 1; const q = p / 4; const m = p % 4; if (n === "0") { zeroCount++; } else { if (zeroCount > 0) { chineseStr += cnNums[0]; } // 归零 zeroCount = 0; chineseStr += cnNums[parseInt(n)] + cnIntRadiance[m]; } if (m === 0 && zeroCount < 4) { chineseStr += cnIntUnits[q]; } } chineseStr += cnIntLast; } // 小数部分 if (decimalNum !== "") { const decLen = decimalNum.length; for (let i = 0; i < decLen; i++) { const n = decimalNum.substr(i, 1); if (n !== "0") { chineseStr += cnNums[Number(n)] + cnDecUnits[i]; } } } if (chineseStr === "") { chineseStr += cnNums[0] + cnIntLast + cnInteger; } else if (decimalNum === "") { chineseStr += cnInteger; } return chineseStr; } /** * @module 数字 */ /** * 转为数字类型 * @description 解决部分浏览器在转换 '08','09'等是0开头时被默认转8进制问题 * @param {string|number} value 转换的值 * @param {number} radix 进制数,默认10进制 * @returns {number} 返回转换后的数字 */ function parseInt$1(value, radix = 10) { if (isNull(value)) { return 0; } return Number.parseInt(String(value), radix); } /** * 转为小数类型 * @param {string|number} value 转换的值 * @returns {number} 返回转换后的数字 */ function parseFloat$1(value) { if (isNull(value)) { return 0.0; } return Number.parseFloat(String(value)); } /** * @module 数组 */ /* 数组计算 */ /** * 数组最小值 * @param {Array} array 数组 * @returns {number} 返回最小值 */ function arrayMin(array) { return Math.min.apply(null, array); } /** * 数组最大值 * @param {array} array 数组 * @returns {number} 返回最大值 */ function arrayMax(array) { return Math.max.apply(null, array); } /** * 数组求和 * @param {Array} array 数组 * @returns {number} 返回和 */ function arraySum(array) { return array.reduce(function (pre, cur) { return pre + cur; }); } /** * 数组求平均值 * @param {Array} array 数组 * @returns {number} 返回平均数 */ function arrayAvg(array) { return arraySum(array) / array.length; } /* 数组比较 */ /** * 数组中是否包含指定的元素 * @param {string|number} value 元素 * @param {Array} array 查找的数组 * @returns {boolean} 返回结果 */ function inArray(value, array) { if (isNull(value)) return false; return array.includes(value); } /** * 比较两个数组是否相等 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {boolean} 返回结果 */ function arrayEquals(array1, array2) { if (array1 === array2) return true; if (array1.length !== array2.length) return false; return array1.every((v, i) => v === array2[i]); } /* 数组操作 */ /** * 生成指定长度的数组 * @param {number} length 长度,默认 0 * @returns {Array} 返回数组 */ function arrayCreate(length = 0) { return [...Array(length).keys()]; } /** * 数组指定位置添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsert(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, value); } return array; } /** * 数组指定位置前面添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsertBefore(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, value); } return array; } /** * 数组指定位置后面添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsertAfter(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, array.splice(index, 1, value)[0]); } return array; } /** * 数组指定位置删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemove(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.splice(index, 1); return array; } /** * 数组指定位置前面删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemoveBefore(array = [], index = 0) { if (index <= 0 || index > array.length - 1) return array; array.splice(index - 1, 1); return array; } /** * 数组指定位置后面删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemoveAfter(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.splice(index + 1, 1); return array; } /** * 数组置顶 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayTop(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.unshift(array.splice(index, 1)[0]); return array; } /** * 数组置尾 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayBottom(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.push(array.splice(index, 1)[0]); return array; } /** * 数组向上移动 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayUp(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; if (index > 0) { array.splice(index - 1, 0, array.splice(index, 1)[0]); } else { array.push(array.splice(index, 1)[0]); } return array; } /** * 数组向下移动 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayDown(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; if (index < array.length - 1) { array.splice(index + 1, 0, array.splice(index, 1)[0]); } else { array.unshift(array.splice(index, 1)[0]); } return array; } /** * 数组交换元素 * @param {Array} array 数组 * @param {number} sourceIndex 原索引 * @param {number} targetIndex 目标索引 * @returns {Array} 返回操作后的数组 */ function arraySwap(array, sourceIndex, targetIndex) { if (sourceIndex < 0 || targetIndex < 0 || sourceIndex > array.length - 1 || targetIndex > array.length - 1) { return array; } [array[targetIndex], array[sourceIndex]] = [array[sourceIndex], array[targetIndex]]; return array; } /** * 数组排序 * @param {Array} array 数组 * @param {number} mode 排序模式,参考常量集合中 数组常量,默认是升序 * @returns {Array} 返回操作后的数组 */ function arraySort(array, mode = SORT.ASC) { return array.sort((a, b) => { switch (mode) { // 升序 case SORT.ASC: return a - b; // 降序 case SORT.DESC: return b - a; // 随机 case SORT.RANDOM: return Math.random() - 0.5; default: return 0; }