JavaScript短小精悍的代码片段
获取随机布尔值(True/False)
使用 Math.random() 会返回 0 到 1 的随机数,之后判断它是否大于 0.5,将会得到一个 50% 概率为 True 或 False 的值const randomBoolean = () => Math.random() >= 0.5; console.log(randomBoolean());判断一个日期是否是工作日
判断给定的日期是否是工作日const isWeekday = (date) => date.getDay() % 6 !== 0; console.log(isWeekday(new Date(2021, 0, 11))); // Result: true (周一) console.log(isWeekday(new Date(2021, 0, 10))); // Result: false (周日)反转字符串
有许多反转字符串的方法,这里使用一种最简单的,使用了 split(),reverse() 和 join()const reverse = str => str.split("").reverse().join(""); reverse("hello world"); // Result: "dlrow olleh"判断当前标签页是否为可视状态
浏览器可以打开很多标签页,下面的代码段就是判断当前标签页是否是激活的标签页const isBrowserTabInView = () => document.hidden; isBrowserTabInView();判断数字为奇数或者偶数
取模运算符 % 可以很好地完成这个任务const isEven = num => num % 2 === 0; console.log(isEven(2)); // Result: true console.log(isEven(3)); // Result: false从 Date 对象中获取时间
使用 Date 对象的 .toTimeString() 方法转换为时间字符串,之后截取字符串即可const timeFromDate = date => date.toTimeString().slice(0, 8); console.log(timeFromDate(new Date(2021, 0, 10, 17, 30, 0))); // Result: "17:30:00" console.log(timeFromDate(new Date())); // Result: 返回当前时间保留指定小数位const toFixed = (n, fixed) => ~~(Math.pow(10, fixed) * n) / Math.pow(10, fixed); // Examples toFixed(25.198726354, 1); // 25.1 toFixed(25.198726354, 2); // 25.19 toFixed(25.198726354, 3); // 25.198 toFixed(25.198726354, 4); // 25.1987 toFixed(25.198726354, 5); // 25.19872 toFixed(25.198726354, 6); // 25.198726检查指定元素是否处于聚焦状态
可以使用 document.activeElement 来判断元素是否处于聚焦状态const elementIsInFocus = (el) => (el === document.activeElement); elementIsInFocus(anyElement) // Result: 如果处于焦点状态会返回 True 否则返回 False检查当前用户是否支持触摸事件const touchSupported = () => { ("ontouchstart" in window || window.DocumentTouch && document instanceof window.DocumentTouch); } console.log(touchSupported()); // Result: 如果支持触摸事件会返回 True 否则返回 False检查当前用户是否是苹果设备
可以使用 navigator.platform 判断当前用户是否是苹果设备const isAppleDevice = /Mac|iPod|iPhone|iPad/.test(navigator.platform); console.log(isAppleDevice); // Result: 是苹果设备会返回 True滚动至页面顶部
window.scrollTo() 会滚动至指定的坐标,如果设置坐标为(0,0),就会回到页面顶部const goToTop = () => window.scrollTo(0, 0); goToTop(); // Result: 将会滚动至顶部获取所有参数的平均值
可以使用 reduce() 函数来计算所有参数的平均值const average = (...args) => args.reduce((a, b) => a + b) / args.length; average(1, 2, 3, 4); // Result: 2.5转换华氏/摄氏const celsiusToFahrenheit = (celsius) => celsius * 9/5 + 32; const fahrenheitToCelsius = (fahrenheit) => (fahrenheit - 32) * 5/9; // Examples celsiusToFahrenheit(15); // 59 celsiusToFahrenheit(0); // 32 celsiusToFahrenheit(-20); // -4 fahrenheitToCelsius(59); // 15 fahrenheitToCelsius(32); // 0防抖
防抖原理:在一定时间内,只有最后一次操作,再过wait毫秒后才执行函数/* @param {Function} func 要执行的回调函数 @param {Number} wait 延迟的时间 @param{Boolean} immediate 是否要立即执行 */ let timeout = null; function debounce(func, wait = 500, immediate = false) { // 清除定时器 if (timeout !== null) clearTimeout(timeout); // 立即执行,此类情况一般用不到 if (immediate) { var callNow = !timeout; timeout = setTimeout(() => { timeout = null; }, wait); if (callNow) typeof func === "function" && func(); } else { // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 timeout = setTimeout(() => { typeof func === "function" && func(); }, wait); } } export default debounce;节流
节流原理:在一定时间内,只能触发一次/** * * @param {Function} func 要执行的回调函数 * @param {Number} wait 延时的时间 * @param {Boolean} immediate 是否立即执行 * @return null */ let timer, flag; function throttle(func, wait = 500, immediate = true) { if (immediate) { if (!flag) { flag = true; // 如果是立即执行,则在wait毫秒内开始时执行 typeof func === "function" && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (!flag) { flag = true // 如果是非立即执行,则在wait毫秒内的结束处执行 timer = setTimeout(() => { flag = false typeof func === "function" && func(); }, wait); } } }; export default throttle 时间格式化time 任何合法的时间格式、秒或毫秒的时间戳 format 时间格式,可选。默认为yyyy-mm-dd,年为"yyyy",月为"mm",日为"dd",时为"hh",分为"MM",秒为"ss",格式可以自由搭 function timeFormat(dateTime = null, fmt = "yyyy-mm-dd") { // 如果为null,则格式化当前时间 if (!dateTime) dateTime = Number(new Date()); // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 if (dateTime.toString().length == 10) dateTime *= 1000; let date = new Date(dateTime); let ret; let opt = { "y+": date.getFullYear().toString(), // 年 "m+": (date.getMonth() + 1).toString(), // 月 "d+": date.getDate().toString(), // 日 "h+": date.getHours().toString(), // 时 "M+": date.getMinutes().toString(), // 分 "s+": date.getSeconds().toString() // 秒 // 有其他格式化字符需求可以继续添加,必须转化成字符串 }; for (let k in opt) { ret = new RegExp("(" + k + ")").exec(fmt); if (ret) { fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) }; }; return fmt; } export default timeFormat多久以前
结合上面的timeFormat时间转换方法一起使用/** * 时间戳转为多久之前 * @param String timestamp 时间戳 * @param String | Boolean format 如果为时间格式字符串,超出一定时间范围,返回固定的时间格式; * 如果为布尔值false,无论什么时间,都返回多久以前的格式 */ import timeFormat from "timeFormat.js"; function timeFrom(dateTime = null, format = "yyyy-mm-dd") { // 如果为null,则格式化当前时间 if (!dateTime) dateTime = Number(new Date()); // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 if (dateTime.toString().length == 10) dateTime *= 1000; let timestamp = + new Date(Number(dateTime)); let timer = (Number(new Date()) - timestamp) / 1000; // 如果小于5分钟,则返回"刚刚",其他以此类推 let tips = ""; switch (true) { case timer < 300: tips = "刚刚"; break; case timer >= 300 && timer < 3600: tips = parseInt(timer / 60) + "分钟前"; break; case timer >= 3600 && timer < 86400: tips = parseInt(timer / 3600) + "小时前"; break; case timer >= 86400 && timer < 2592000: tips = parseInt(timer / 86400) + "天前"; break; default: // 如果format为false,则无论什么时间戳,都显示xx之前 if(format === false) { if(timer >= 2592000 && timer < 365 * 86400) { tips = parseInt(timer / (86400 * 30)) + "个月前"; } else { tips = parseInt(timer / (86400 * 365)) + "年前"; } } else { tips = timeFormat(timestamp, format); } } return tips; } export default timeFrom; 手机号中间4位加密export const phoneFormat = (phone = 0) => { return String(phone).replace(/^(d{3})d{4}(d+)$/, "$1****$2"); };格式化显示银行卡号
1111 2222 3333 4444 555export function trimCardNumber(value) { value = String(value || "") .replace(/s/g, "") .replace(/(.{4})/g, "$1 "); return value; }格式化显示手机号
138 0000 0831 export function formatPhone(val) { if (val) { const matches = /^(d{3})(d{4})(d{4})$/.exec(val); if (matches) { return matches[1] + " " + matches[2] + " " + matches[3]; } } return val; }常用正则表达式// 验证手机号 const REGEXP_PHONE = /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/; // 验证身份证号 const REGEXP_IDCARD = /^(^[1-9]d{7}((0d)|(1[0-2]))(([0|1|2]d)|3[0-1])d{3}$)|(^[1-9]d{5}[1-9]d{3}((0d)|(1[0-2]))(([0|1|2]d)|3[0-1])((d{4})|d{3}[Xx])$)$/;
验证电子邮箱格式function email(value) { return /^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/.test(value); }
验证手机格式function mobile(value) { return /^1[23456789]d{9}$/.test(value) }
验证URL格式function url(value) { return /http(s)?://([w-]+.)+[w-]+(/[w-./?%&=]*)?/.test(value) }
验证日期格式function date(value) { return !/Invalid|NaN/.test(new Date(value).toString()) }
验证ISO类型的日期格式function dateISO(value) { return /^d{4}[/-](0?[1-9]|1[012])[/-](0?[1-9]|[12][0-9]|3[01])$/.test(value) }
验证十进制数字function number(value) { return /^(?:-?d+|-?d{1,3}(?:,d{3})+)?(?:.d+)?$/.test(value) }
验证整数function digits(value) { return /^d+$/.test(value) }
验证身份证号码function idCard(value) { return /^[1-9]d{5}[1-9]d{3}((0d)|(1[0-2]))(([0|1|2]d)|3[0-1])d{3}([0-9]|X)$/.test( value) }
是否车牌号function carNo(value) { // 新能源车牌 const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/; // 旧车牌 const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/; if (value.length === 7) { return creg.test(value); } else if (value.length === 8) { return xreg.test(value); } else { return false; } }
金额,只允许2位小数function amount(value) { //金额,只允许保留两位小数 return /^[1-9]d*(,d{3})*(.d{1,2})?$|^0.d{1,2}$/.test(value); }
只能输入字母function letter(value) { return /^[a-zA-Z]*$/.test(value); }
只能是字母或者数字function enOrNum(value) { //英文或者数字 let reg = /^[0-9a-zA-Z]*$/g; return reg.test(value); }
是否固定电话function landline(value) { let reg = /^d{3,4}-d{7,8}(-d{3,4})?$/; return reg.test(value); }
判断是否为空function empty(value) { switch (typeof value) { case "undefined": return true; case "string": if (value.replace(/(^[ r]*)|([ r]*$)/g, "").length == 0) return true; break; case "boolean": if (!value) return true; break; case "number": if (0 === value || isNaN(value)) return true; break; case "object": if (null === value || value.length === 0) return true; for (var i in value) { return false; } return true; } return false; }
是否json字符串function jsonString(value) { if (typeof value == "string") { try { var obj = JSON.parse(value); if (typeof obj == "object" && obj) { return true; } else { return false; } } catch (e) { return false; } } return false; }
密码强度的校验
说明:密码中必须包含字母、数字、特称字符,至少8个字符,最多30个字符const passwordReg = /(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,30}/ const password1 = "sunshine_Lin12345.." console.log(passwordReg.test(password1)) // true const password2 = "sunshineLin12345" console.log(passwordReg.test(password2)) // false
全局唯一标识符
guid(length = 32, firstU = true, radix = 62) length guid的长度,默认为32,如果取值null,则按rfc4122标准生成对应格式的随机数 firstU 首字母是否为"u",如果首字母为数字情况下,不能用作元素的id或者class,默认为true radix 生成的基数,默认为62,用于生成随机数字符串 function guid(len = 32, firstU = true, radix = null) { let chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""); let uuid = []; radix = radix || chars.length; if (len) { // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; } else { let r; // rfc4122标准要求返回的uuid中,某些位为固定的字符 uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-"; uuid[14] = "4"; for (let i = 0; i < 36; i++) { if (!uuid[i]) { r = 0 | Math.random() * 16; uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } } } // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class if (firstU) { uuid.shift(); return "u" + uuid.join(""); } else { return uuid.join(""); } } export default guid;
对象转URL参数
queryParams(data, isPrefix = true, arrayFormat = "brackets")/** * 对象转url参数 * @param {*} data,对象 * @param {*} isPrefix,是否自动加上"?" */ function queryParams(data = {}, isPrefix = true, arrayFormat = "brackets") { let prefix = isPrefix ? "?" : "" let _result = [] if (["indices", "brackets", "repeat", "comma"].indexOf(arrayFormat) == -1) arrayFormat = "brackets"; for (let key in data) { let value = data[key] // 去掉为空的参数 if (["", undefined, null].indexOf(value) >= 0) { continue; } // 如果值为数组,另行处理 if (value.constructor === Array) { // e.g. {ids: [1, 2, 3]} switch (arrayFormat) { case "indices": // 结果: ids[0]=1&ids[1]=2&ids[2]=3 for (let i = 0; i < value.length; i++) { _result.push(key + "[" + i + "]=" + value[i]) } break; case "brackets": // 结果: ids[]=1&ids[]=2&ids[]=3 value.forEach(_value => { _result.push(key + "[]=" + _value) }) break; case "repeat": // 结果: ids=1&ids=2&ids=3 value.forEach(_value => { _result.push(key + "=" + _value) }) break; case "comma": // 结果: ids=1,2,3 let commaStr = ""; value.forEach(_value => { commaStr += (commaStr ? "," : "") + _value; }) _result.push(key + "=" + commaStr) break; default: value.forEach(_value => { _result.push(key + "[]=" + _value) }) } } else { _result.push(key + "=" + value) } } return _result.length ? prefix + _result.join("&") : "" } export default queryParams; console.log(queryParams({name:"li",age:20})) // 结果:?name=li&age=20 const data = {name: "冷月夜",fruits: ["apple", "banana", "orange"]} queryParams(this.data, true, "indices"); // 结果为:?name=冷月夜&fruits[0]=apple&fruits[1]=banana&fruits[2]=orange queryParams(this.data, true, "brackets"); // 结果为:?name=冷月夜&fruits[]=apple&fruits[]=banana&fruits[]=orange queryParams(this.data, true, "repeat"); // 结果为:?name=冷月夜&fruits=apple&fruits=banana&fruits=orange queryParams(this.data, true, "comma"); // 结果为:?name=冷月夜&fruits=apple,banana,orange
去除空格str 字符串 pos 去除那些位置的空格,可选为:both-默认值,去除两端空格,left-去除左边空格,right-去除右边空格,all-去除包括中间和两端的所有空格 function trim(str, pos = "both") { if (pos == "both") { return str.replace(/^s+|s+$/g, ""); } else if (pos == "left") { return str.replace(/^s*/, ""); } else if (pos == "right") { return str.replace(/(s*$)/g, ""); } else if (pos == "all") { return str.replace(/s+/g, ""); } else { return str; } } export default trim数组排序
sort排序// 对数字进行排序,简写 const arr = [3, 2, 4, 1, 5] arr.sort((a, b) => a - b) console.log(arr) // [1, 2, 3, 4, 5] // 对字母进行排序,简写 const arr = ["b", "c", "a", "e", "d"] arr.sort() console.log(arr) // ["a", "b", "c", "d", "e"]
冒泡排序function bubbleSort(arr) { let len = arr.length for (let i = 0; i < len - 1; i++) { // 从第一个元素开始,比较相邻的两个元素,前者大就交换位置 for (let j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { let num = arr[j] arr[j] = arr[j + 1] arr[j + 1] = num } } // 每次遍历结束,都能找到一个最大值,放在数组最后 } return arr } //测试 console.log(bubbleSort([2, 3, 1, 5, 4])) // [1, 2, 3, 4, 5]获取URL参数
URLSearchParams 方法// 创建一个URLSearchParams实例 const urlSearchParams = new URLSearchParams(window.location.search); // 把键值对列表转换为一个对象 const params = Object.fromEntries(urlSearchParams.entries());
split方法function getParams(url) { const res = {} if (url.includes("?")) { const str = url.split("?")[1] const arr = str.split("&") arr.forEach(item => { const key = item.split("=")[0] const val = item.split("=")[1] res[key] = decodeURIComponent(val) // 解码 }) } return res } // 测试 const user = getParams("http://www.baidu.com?user=%E9%98%BF%E9%A3%9E&age=16") console.log(user) // { user: "阿飞", age: "16" }