@ivujs/i-utils
Version:
前端模块化 JavaScript 工具库
2,040 lines (1,862 loc) • 477 kB
JavaScript
/*
* @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