UNPKG

@ivujs/i-utils

Version:

前端模块化 JavaScript 工具库

2,040 lines (1,862 loc) 477 kB
/* * @ivujs/i-utils v1.1.1 * Copyright 2021-2024, <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'; /** * 数组常量 */ const SORT = { // 降序 DESC: 0, // 升序 ASC: 1, // 随机排序 RANDOM: 2, }; /** * 数学常量 */ const MATH = { // 正常四舍五入,如:1.354保留两位是1.35;1.355保留两位是1.36; ROUND: 0, // 向下舍出,如:1.354保留两位是1.35;1.355保留两位是1.35; ROUND_FLOOR: 1, }; /** * 语言常量 */ const LANG = { // 中文 ZH: "zh", // 英文 EN: "en", }; /** * 正则常量 */ const REGEXP = { // 中文汉字 CH: /^[\u4E00-\u9FA5]+$/, // 英文字母 EN: /^[a-zA-Z]$/, // 小写字母 LOWER_CASE: /^[a-z]+$/, // 大写字母 UPPER_CASE: /^[A-Z]+$/, // 中文姓名,2-16位 CH_NAME: /^[\u4e00-\u9fa5·]{2,16}$/, // 英文姓名,0-20位 EN_NAME: /(^[a-zA-Z][a-zA-Z\s]{0,20}[a-zA-Z]$)/, // 数字,包含正数和负数 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等信息 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,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}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/, // 是外链,http,https,mail,tel电话 EXTERNAL: /^(http?:|https?:|mailto:|tel:)/, // 是函数字符串,包括async异步函数和箭头函数 FUNCTION_STR: /^(function\([\w,\s]*\)\s*{[\s\S]*})|^\(\s*([\w,\s]*)\s*\)\s*=>\s*{[\s\S]*}|^(async\s*function\s*\([\w,\s]*\)\s*{[\s\S]*}\)\s*{[\s\S]*})|^(async\(\s*([\w,\s]*)\s*\)\s*=>\s*{[\s\S]*})$/, }; /** * 日期常量 */ 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"], }, }; /** * 去除字符串前后位置空格 * @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 toUpper(value) { return String(value).toLocaleUpperCase(); } /** * 字符串转小写 * @param {String} value 参数 * @returns {String} 返回处理后的字符串 */ function toLower(value) { 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(); } // 短横 if (value.indexOf("-") > 0) { return value.replace(/-/g, "_").toLowerCase(); } // 帕斯卡 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(); } } /** * 转为 kebab-case 短横命名 * @description 支持 下划线,驼峰命名,帕斯卡命名 * @param {String} value 参数 * @returns {String} 返回处理后的字符串 */ function toKebabCase(value) { // 下划线 if (value.indexOf("_") > 0) { return value.replace(/_/g, "-").toLowerCase(); } // 驼峰 if (/^[a-z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { return value.replace(/([A-Z])/g, "-$1").toLowerCase(); } // 帕斯卡 if (/^[A-Z]$/.test(value.charAt(0)) && !(value.indexOf("-") > 0 || value.indexOf("_") > 0)) { let newStr = value.charAt(0).toLowerCase() + value.slice(1); return newStr.replace(/([A-Z])/g, "-$1").toLowerCase(); } } /** * 转为 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 { return value; } } /** * 转为 PascalCase 帕斯卡命名 * @description 支持 下划线命名,短横命名,驼峰命名 * @param {String} value 参数 * @returns {String} 返回处理后的字符串 */ function toPascalCase(value) { // 下划线 if (value.indexOf("_") > 0) { let newStr = value.replace(/\_(\w)/g, function (all, letter) { return letter.toUpperCase(); }); return newStr.charAt(0).toUpperCase() + newStr.slice(1); } // 短横 else if (value.indexOf("-") > 0) { let 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 { return value; } } /* 字符串格式化 */ /** * 字符串中是否包含指定的元素 * @param {String} value 包含的元素 * @param {String} str 查找的字符串 * @returns {Boolean} 返回true和false */ function inString(value, str) { return str.includes(value); } /** * 数字前补齐0达到指定位数 * @description 相当于原生的 padStart(2,'0') * @param {Number|String} value 补零的数字 * @param {Number} maxLength 补齐0后的最大长度,默认2位 * @returns {String} 返回补0后指定位数的字符串 */ function zeroStart(value, maxLength = 2) { 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 zeroEnd(value, maxLength = 2) { let len = value.toString().length; while (len < maxLength) { value = value + "0"; len++; } return value; } /** * 格式化千分位数字 * @description 支持任意数据传参,如果非数字则不会格式化,并返回原数据 * @param {Number|String} num 数字 * @returns {String} 返回格式化后的千分位数字 */ function formatThousand(num) { if (!parseFloat(num)) return num; num = String(num); let 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) { // 汉字的数字 let cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]; // 基本单位 let cnIntRadiance = ["", "拾", "佰", "仟"]; // 对应整数部分扩展单位 let cnIntUnits = ["", "万", "亿", "兆"]; // 对应小数部分单位 let cnDecUnits = ["角", "分", "毫", "厘"]; // 整数金额时后面跟的字符 let cnInteger = "整"; // 整型完以后的单位 let cnIntLast = "元"; // 最大处理的数字 let maxNum = Number("999999999999999.9999"); // 金额整数部分 let integerNum; // 金额小数部分 let decimalNum; // 输出的中文金额字符串 let chineseStr = ""; // 分离金额后用的数组,预定义 let parts; if (money === "") { // 不能用== return ""; } money = parseFloat(money); if (money >= maxNum) { // 超出最大处理数字,抛出异常 throw new Error("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; let IntLen = integerNum.length; for (let i = 0; i < IntLen; i++) { let n = integerNum.substr(i, 1); let p = IntLen - i - 1; let q = p / 4; let 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 !== "") { let decLen = decimalNum.length; for (let i = 0; i < decLen; i++) { let 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; } /** * 转为数字类型 * @description 解决部分浏览器在转换 '08','09'等是0开头时被默认转8进制问题 * @param {String,number} value 转换的值 * @param {Number} radix 进制数,默认10进制 * @returns {Number} 返回转换后的数字 */ function parseInt$1(value, radix = 10) { return Number.parseInt(value, radix); } /** * 判断是整数 * @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 {Number} 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$4(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 === "Function"; } /** * 判断类型是异步函数 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 || value === NaN ); } /** * 判断非数字 * @param {*} value 参数 * @returns {Boolean} 返回结果 */ function isNaN(value) { // window的isNaN函数是有缺陷的,空数组/数组有一个元素,null,空字符串 都会被认为是数字 return window.isNaN(value) || isArray$4(value) || value == null || 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) { return isNull(value) || !(Object.keys(value) || value).length; } /** * 判断值不为空 * @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 {String|Number} value1 参数1 * @param {String|Number} value2 参数2 * @returns {Boolean} 返回结果 */ function equals(value1, value2) { return Object.is(value1, value2); } /** * 判断两个值是否相等(忽略大小写) * @param {String|Number} value1 参数1 * @param {String|Number} value2 参数2 * @returns {Boolean} 返回结果 */ function equalsIgnoreCase(value1, value2) { return Object.is(value1.toLowerCase(), value2.toLowerCase()); } /** * 深度对比数据 * @description 可以对比任意数据,对象,数组,日期等也可深度对比,对象不区分先后顺序 * @param {*} x 数据1 * @param {*} y 数据2 * @returns {Boolean} 返回结果 */ function deepCompare(x, y) { let i, l, leftChain, rightChain; function compare2Objects(x, y) { let p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === "number" && typeof y === "number") { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ( (typeof x === "function" && typeof y === "function") || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number) ) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof x[p]) { case "object": case "function": leftChain.push(x); rightChain.push(y); if (!compare2Objects(x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } } return true; } if (arguments.length < 1) { return true; // Die silently? Don't know how to handle such case, please help... // throw "Need two or more arguments to compare"; } for (i = 1, l = arguments.length; i < l; i++) { leftChain = []; rightChain = []; if (!compare2Objects(arguments[0], arguments[i])) { return false; } } return true; } /* 数组计算 */ /** * 数组最小值 * @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 array; } }); } /** * 数组元素去重 * @param {Array} array 数组 * @returns {Array} 返回操作后的数组 */ function arrayUnique(array) { if (isEmpty(array)) return []; return Array.from(new Set(array)); } /** * 数组打乱元素 * @description 可以适用于一些抽奖人员列表打乱顺序 * @param {Array} array 数组 * @returns {Array} 返回操作后的数组 */ function arrayShuffle(array) { for (let i = 1; i < array.length; i++) { const random = Math.floor(Math.random() * (i + 1)); [array[random], array[i]] = [array[i], array[random]]; } return array; } /* 数组转换 */ /** * 普通数组转树形结构 * @description 包含id和pid属性关系的一维数组,转为children的树形结构 * @param {Array} array 数组 * @param {Object} setting 配置项 * @returns {Array} 返回树形节点 */ function arrayToTree(array, setting = { key: "id", parentKey: "pid", childrenKey: "children" }) { let key = setting.key, parentKey = setting.parentKey, childrenKey = setting.childrenKey; // 数组或者key是否为空 if (!array || array.length === 0 || !key || key === "") return []; // 获得子节点方法 const nodeChildren = function (node, childrenKey, newChildren) { if (!node) { return null; } if (typeof newChildren !== "undefined") { node[childrenKey] = newChildren; } return node[childrenKey]; }; // 声明变量 let result = []; let tempMap = {}; for (let i = 0; i < array.length; i++) { // 如果源数据数组中有children,则需要删除掉,否则会导致和之前的children合并 array[i][childrenKey] && delete array[i][childrenKey]; tempMap[array[i][key]] = array[i]; } for (let i = 0; i < array.length; i++) { let parent = tempMap[array[i][parentKey]]; if (parent && array[i][key] !== array[i][parentKey]) { let children = nodeChildren(parent, childrenKey); if (!children) { children = nodeChildren(parent, childrenKey, []); } children.push(array[i]); } else { result.push(array[i]); } } // 返回结果 return result; } /** * 树形结构转普通数组 * @param {Array} nodes 树形节点 * @param {Object} setting 配置项 * @returns {Array} 返回普通数组 */ function treeToArray(nodes, setting = { childrenKey: "children" }) { let childrenKey = setting.childrenKey; let result = []; for (let node of nodes) { // 删除掉多余空的children if (node[childrenKey] && !node[childrenKey].length) { delete node[childrenKey]; } result.push(node); // 继续执行 if (node[childrenKey] && node[childrenKey].length) { let array = treeToArray(node[childrenKey], setting); array && result.push(...array); } } // 返回结果 return result; } /* 数组求并集,交集,差集等 */ /** * 数组求并集 * @description 数组1 和 数组2 合并一起的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayUnion(array1, array2) { return [...new Set(array1.concat(array2))]; } /** * 数组求交集 * @description 数组1 和 数组2 相同的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayIntersect(array1, array2) { return [...new Set(array1)].filter((item) => array2.includes(item)); } /** * 数组求差集 * @description 数组1 中不包含 数组2 的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayDifference(array1, array2) { return [...new Set(array1)].filter((item) => !array2.includes(item)); } /** * 数组求补集 * @description 数组1 和 数组2 不相同的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayComplement(array1, array2) { return [ ...[...new Set(array1)].filter((item) => !array2.includes(item)), ...[...new Set(array2)].filter((item) => !array1.includes(item)), ]; } /* 对象转换 */ /** * map转object * @param {Map} map 参数 * @returns {Object} 返回Object */ function mapToObject(map) { let obj = Object.create(null); for (let [k, v] of map) { obj[k] = v; } return obj; } /** * map转json字符串 * @param {Map} map 参数 * @returns {String} 返回Json字符串 */ function mapToJson(map) { return JSON.stringify(mapToObject(map)); } /** * object转map * @param {Object} obj 参数 * @returns {Map} 返回Map */ function objectToMap(obj) { let map = new Map(); for (let k of Object.keys(obj)) { map.set(k, obj[k]); } return map; } /** * json字符串转map * @param {String} json json字符串 * @returns {Map} 返回Map */ function jsonToMap(json) { return objectToMap(JSON.parse(json)); } /** * json对象转json字符串 * @param {Object} json json对象 * @returns {String} 返回Json字符串 */ function stringifyJson(json) { return JSON.stringify(json); } /** * json字符串转json对象 * @param {String} json json字符串 * @returns {Object} 返回Json对象 */ function parseJson(json) { if (isEmpty(json)) return; return JSON.parse(json); } /* 数据拷贝,对比,合并等操作 */ /** * 浅拷贝数据 * @param {*} source 拷贝的数据 * @returns {*} 返回浅拷贝的数据 */ function clone(source) { return Object.assign(source); } /** * 深拷贝数据 * @param {*} source 拷贝的数据 * @returns {*} 返回深拷贝的数据 */ function cloneDeep(source) { // Object if (isObject(source)) { let copy = {}; for (let attr in source) { if (source.hasOwnProperty(attr)) copy[attr] = cloneDeep(source[attr]); } return copy; } // Array else if (isArray$4(source)) { let copy = []; for (let i = 0, len = source.length; i < len; i++) { copy[i] = cloneDeep(source[i]); } return copy; } // Date else if (isDate(source)) { let copy = new Date(); copy.setTime(source.getTime()); return copy; } // Other 原路返回源数据 else { return source; } } /** * 比较两个对象是否相等 * @description 方法只能对比简单的对象,不能包含function,另外对象的属性顺序不一致也是相等的 * @param {Object} obj1 对象1 * @param {Object} obj2 对象2 * @returns {Boolean} 返回true和false */ function objectEquals(obj1, obj2) { // 比较值相等 if (obj1 === obj2) { return true; } // 比较Date if (obj1 instanceof Date && obj2 instanceof Date) { return obj1.getTime() === obj2.getTime(); } // 对象比较引用 if (!obj1 || !obj2 || (typeof obj1 !== "object" && typeof obj2 !== "object")) { return obj1 === obj2; } // 比较原型 if (obj1.prototype !== obj2.prototype) { return false; } // 比较对象的值 const keys = Object.keys(obj1); if (keys.length !== Object.keys(obj2).length) { return false; } else { return keys.every((k) => objectEquals(obj1[k], obj2[k])); } } /** * 合并对象 * @param {Object} target 目标对象 * @param {Object[]} source 原对象列表 * @returns {Object} 返回合并后的对象 */ function merge(target, ...source) { return Object.assign(target, ...source); } /* 根据字符串属性路径操作目标对象 */ /** * 根据字符串属性路径获取目标对象的值 * @example * let res = {code:200, data:{rows:[], pages:{current:1,pageSize:20}}} * this._getTargetValueByPath(res, 'data.pages.pageSize'); // 这里会输出20 * @param {Object} target 目标对象 * @param {String} path 字符串属性路径 * @returns {Object} 返回目标对象 */ function getTargetValueByPath(target, path = "data") { const paths = (path || "data").split("."); let data = target; // 属性总个数 let lastIndex = paths.length - 1; for (const index in paths) { // 如果路径中没有该属性,则创建一个 if (data[paths[index]] === null || data[paths[index]] === undefined) { data[paths[index]] = Number(index) !== lastIndex ? {} : undefined; } // 逐层向下找到对应属性的值 data = data[paths[index]]; } return data; } /** * 根据字符串属性路径设置目标对象的值 * @example * let res = {code:200, data:{rows:[], pages:{current:1,pageSize:20}}} * this._setTargetValueByPath(res, 'data.pages.pageSize', 30); // 打印res对象会发现pageSize的值改为了30 * @param {Object} target 目标对象 * @param {String} path 字符串属性路径 * @param {*} value 值 */ function setTargetValueByPath(target, path = "data", value) { const paths = (path || "data").split("."); // 变量表达式拼接,最终结果如:target['personInfo']['personName']='xxx'; let fxStr = ""; for (const name of paths) { fxStr += `['${name}']`; } const fn = new Function("target", `target${fxStr}=${value}`); fn(target); } /** * 防抖函数 * @description 事件执行后,在延迟时间内如果再次执行,会清空定时器重新延迟执行,举例:用户在输入框进行输入搜索,最终是会获取到最后一次输入,节约请求资源 * @param {Function} fn 目标函数 * @param {Number} delay 延迟时间,单位毫秒,默认 1*1000 毫秒 * @param {Boolean} immediate 是否立即执行,默认true * @returns {Function} 返回function() */ function debounce(fn, delay = 1 * 1000, immediate = true) { let timer; return function () { const _args = arguments; // 先关闭定时器 if (timer) clearTimeout(timer); // 立即执行判断 if (immediate) { // 如果需要立即执行 // 开启新定时器防止短时间内再次触发 const canExecute = !timer; timer = setTimeout(function () { timer = null; }, delay); if (canExecute) fn.apply(this, _args); } else { // 如果不需要立即执行 // 每次触发开启新定时器即可 timer = setTimeout(function () { fn.apply(this, _args); }, delay); } }; } /** * 节流函数 * @description 高频触发时,在指定时间间隔内只执行一次,举例:监听页面滚动,不会频繁触发,只会在固定时间内获取一次 * @param {Function} fn 目标函数 * @param {Number} interval 时间间隔,单位毫秒,默认1*1000毫秒 * @returns {Function} 返回function() */ function throttle(fn, interval = 1 * 1000) { let timer; return function () { const _args = arguments; // 有定时器则返回 if (timer) return; timer = setTimeout(() => { timer = null; fn.apply(this, _args); }, interval); }; } /** * 睡眠延迟执行 * @description 需要配合 async/await 来达到延迟效果 * @param {Number} delay 延迟时间,单位毫秒,默认1*1000毫秒 */ function sleep(delay = 1 * 1000) { return new Promise((resolve) => setTimeout(resolve, delay)); } /* 快捷日期 */ /** * 今天 *@returns {String} 返回日期字符串 */ function today() { return getDate(); } /** * 昨天 * @returns {String} 返回日期字符串 */ function yesterday() { return formatDate(addDate(new Date(), -1)); } /** * 明天 *@returns {String} 返回日期字符串 */ function tomorrow() { return formatDate(addDate(new Date(), +1)); } /** * 上周(7天前日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function lastWeek(date = new Date()) { return formatDate(addDate(date, -7)); } /** * 下周(7天后日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function nextWeek(date = new Date()) { return formatDate(addDate(date, +7)); } /** * 上个月(30天前日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function lastMonth(date = new Date()) { return formatDate(addDate(date, -30)); } /** * 下个月(30天后日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function nextMonth(date = new Date()) { return formatDate(addDate(date, +30)); } /** * 上一年(365天前日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function lastYear(date = new Date()) { return formatDate(addDate(date, -365)); } /** * 下一年(365天后日期) * @param {Date} date 日期参数,默认当前日期 * @returns {String} 返回日期字符串 */ function nextYear(date = new Date()) { return formatDate(addDate(date, +365)); } /* 判断当前日期 */ /** * 是否为上午 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isAM(date = new Date()) { return date.getHours() < 12; } /** * 是否为下午 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isPM(date = new Date()) { return date.getHours() >= 12; } /** * 是否为今天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isToday(date = new Date()) { // 此刻日期 let nowDate = new Date(); // 判断日期 return ["getFullYear", "getMonth", "getDate"].every((i) => nowDate[i]() === date[i]()); } /** * 是否为昨天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isYesterday(date = new Date()) { // 计算时间差 let startTime = date.getTime(); let nowTime = Date.now(); let diffTime = nowTime - startTime; let diffDay = parseInt$1(diffTime / (1000 * 60 * 60 * 24)); return diffDay === 1; } /** * 是否为前天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isBeforeYesterday(date = new Date()) { // 计算时间差 let startTime = date.getTime(); let nowTime = Date.now(); let diffTime = nowTime - startTime; let diffDay = parseInt$1(diffTime / (1000 * 60 * 60 * 24)); return diffDay === 2; } /** * 是否为明天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isTomorrow(date = new Date()) { // 计算时间差 let startTime = date.getTime(); let nowTime = Date.now(); let diffTime = startTime - nowTime; let diffDay = parseInt$1(diffTime / (1000 * 60 * 60 * 24)); return diffDay === 1; } /** * 是否为后天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isAfterTomorrow(date = new Date()) { // 计算时间差 let startTime = date.getTime(); let nowTime = Date.now(); let time = startTime - nowTime; let diffDay = parseInt$1(time / (1000 * 60 * 60 * 24)); return diffDay === 2; } /** * 是否为工作日 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isWorkday(date = new Date()) { let dayOfWeek = getDayOfWeek(date); return dayOfWeek !== 6 && dayOfWeek !== 7; } /** * 是否为周末(周六和周日) * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isWeekend(date = new Date()) { let dayOfWeek = getDayOfWeek(date); return dayOfWeek === 6 || dayOfWeek === 7; } /** * 是否为本周第一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isFirstDayOfWeek(date = new Date()) { return getDayOfWeek(date) === 1; } /** * 是否为本周最后一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isLastDayOfWeek(date = new Date()) { return getDayOfWeek(date) === 7; } /** * 是否为本月第一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isFirstDayOfMonth(date = new Date()) { return getDayOfMonth(date) === 1; } /** * 是否为本月最后一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isLastDayOfMonth(date = new Date()) { return getDayOfMonth(date) === getDaysOfMonth(date); } /** * 是否为本年第一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isFirstDayOfYear(date = new Date()) { return getDayOfYear(date) === 1; } /** * 是否为本年最后一天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isLastDayOfYear(date = new Date()) { return getDayOfYear(date) === getDaysOfYear(date); } /* 判断年 */ /** * 是否为闰年 * @description 闰年366天,平年365天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isLeapYear(date = new Date()) { let year = date.getFullYear(); return (year % 100 !== 0 && year % 4 === 0) || year % 400 === 0; } /** * 是否为平年 * @description 闰年366天,平年365天 * @param {Date} date 日期参数,默认当前日期 * @returns {Boolean} 返回结果 */ function isCommonYear(date = new Date()) { return !isLeapYear(date); } /* 比较日期区间 */ /** * 是否在日期之前 * @param {Date} startDate 开始日期 * @param {Date} endDate 结束日期,默认当前日期 * @returns {Boolean} 返回结果 */ function isBefore(startDate, endDate = new Date()) { // 计算时间差 let startTime = startDate.getTime(); let endTime = endDate.getTime(); let diffTime = startTime - endTime; return diffTime < 0; } /** * 是否在日期之后 * @param {Date} startDate 开始日期 * @param {Date} endDate 结束日期,默认当前日期 * @returns {Boolean} 返回结果 */ function isAfter(startDa