regexp
判断手机号码
{/*** @description 判断手机号码* @param {String|Number} tel* @returns {Boolean}*/function isPhoneNum(tel) {return /^1[34578]\d{9}$/.test(tel);}/*** @description 判断是否为手机号 (百度)* @param {String|Number} tel* @returns {Boolean}*/function isPhoneNum(tel) {return /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/.test(tel)}/*** @description 手机号(严谨), 根据工信部2019年最新公布的手机号段* @param {String|Number} tel* @returns {Boolean}*/function isPhoneNum(tel) {return /^1((3[\d])|(4[5,6,7,9])|(5[0-3,5-9])|(6[5-7])|(7[0-8])|(8[\d])|(9[1,8,9]))\d{8}$/.test(tel);}}
判断是否为邮箱地址
{/*** @description 判断是否为邮箱地址* @param {String} email* @returns {Boolean}*/function isEmail(email) {return /^([a-zA-Z0-9_\-])+@([a-zA-Z0-9_\-])+(\.[a-zA-Z0-9_\-])+$/.test(email);}}
验证身份证号码
{/*** @description 验证身份证号码(身份证号码可能为15位或18位,15位为全数字,18位中前17位为数字,最后一位为数字或者X)* @param {String} idCard* @returns {Boolean}*/function isCardNo(idCard) {return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(idCard);}/*** @description 验证身份证号码* @param {String} idCard* @returns {Boolean}*/function isIDCard(idCard) {return /(^\d{8}(0\d|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0\d|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/.test(idCard)}}
帐号是否合法
{// 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线组合var regx = /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/;}
去除首尾的’/‘
{// 去除首尾的'/'var str = '/asdf//';str = str.replace(/^\/*|\/*$/g, '');}
去除空格 - trim()
{String.prototype.trim = function () {return this.replace(/^\s+/, "").replace(/\s+$/, "");};}{// 正则实现trim()功能function myTrim(str) {let reg = /^\s+|\s+$/g;return str.replace(reg, "");}let str = " wcd ";console.log(myTrim(str)); // wcd}
日期
{// 判断日期格式是否符合 '2017-05-11'的形式,简单判断,只判断格式var regx = /^\d{4}\-\d{1,2}\-\d{1,2}$/// 判断日期格式是否符合 '2017-05-11'的形式,严格判断(比较复杂)var regx = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;}
账号相关(用户名-密码)
{// 用户名正则var regx1 = /^[a-zA-Z0-9_-]{4,16}$/;// 密码强度正则,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符var regx2 = /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/;}
车牌号正则
{// 车牌号正则var regx = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/;}{// 新能源车牌号var regx1 = /[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领 A-Z]{1}[A-HJ-NP-Z]{1}(([0-9]{5}[DF])|([DF][A-HJ-NP-Z0-9][0-9]{4}))$/;// 非新能源车牌号var regx2 = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领 A-Z]{1}[A-HJ-NP-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/;// 车牌号(新能源+非新能源)var regx3 = /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领 A-Z]{1}[A-HJ-NP-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领 A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9 挂学警港澳]{1})$/;}
过滤HTML标签
{// 过滤HTML标签var str = "<p>dasdsa</p>nice <br> test</br>"var regx = /<[^<>]+>/g;str = str.replace(regx, '');}
URL
{// URL正则var regx = /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;// 合法urifunction validateURL(textval) {const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/return urlregex.test(textval)}// 操作URL查询参数const params = new URLSearchParams(location.search.replace(/\?/ig, "")); // location.search = "?name=yajun&sex=female"params.has("yajun"); // trueparams.get("sex"); // "female"}
生成随机HEX色值
{// 生成随机HEX色值const RandomColor = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");const color = RandomColor();// color => "#f03665"}
生成星级评分
{// 生成星级评分const StartScore = rate => "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);const start = StartScore(3);// start => "★★★"}
千位分隔符
{/*** @description 千位分隔符(格式化金钱)* @param {String|Number} num* @returns {string}*/function thousandNum(num) {var regx = /\d{1,3}(?=(\d{3})+$)/g;return (num + '').replace(regx, '$&,') // $&表示与regx相匹配的字符串}/*** @description 千位分隔符(格式化金钱)* @param {String|Number} num* @returns {string}*/function thousandNum(num) {return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");}// thousandNum(123456789) => "123,456,789"}
大小写字母
{/* 小写字母*/function validateLowerCase(str) {const reg = /^[a-z]+$/return reg.test(str)}/* 大写字母*/function validateUpperCase(str) {const reg = /^[A-Z]+$/return reg.test(str)}/* 大小写字母*/function validatAlphabets(str) {const reg = /^[A-Za-z]+$/return reg.test(str)}}
判空
{// 判断是否为空function validatenull(val) {if (typeof val === 'boolean') {return false}if (val instanceof Array) {if (val.length === 0) return true} else if (val instanceof Object) {if (JSON.stringify(val) === '{}') return true} else {if (val === 'null' || val == null || val === 'undefined' || val === undefined || val === '') return truereturn false}return false}}
下划线命名到驼峰命名
const strToCamel = (str) => str.replace(/(^|_)(\w)/g, (m, $1, $2) => $2.toUpperCase());console.log(strToCamel("aa_bb_cc_d_e_f"));
other
localStorage(sessionStorage)
const localStorage = window.localStorage;const sessionStorage = window.sessionStorage;// 设置localStorage存储数据export const setLocal = (name, content) => {if (!name) return;if (typeof content !== "string") {content = JSON.stringify(content);}localStorage.setItem(name, content);};// 获取localStorage存储数据export const getLocal = (name) => {if (!name) return;let value = localStorage.getItem(name);if (value !== null) {try {value = JSON.parse(value);} catch (error) {value = value;}}return value;};// 删除localStorage存储数据export const removeLocal = (name) => {if (!name) return;localStorage.removeItem(name);};// 设置sessionStorage存储数据export const setSession = (name, content) => {if (!name) return;if (typeof content !== "string") {content = JSON.stringify(content);}sessionStorage.setItem(name, content);};// 获取sessionStorage存储数据export const getSession = (name) => {if (!name) return;let value = sessionStorage.getItem(name);if (value !== null) {try {value = JSON.parse(value);} catch (error) {value = value;}}return value;};// 删除sessionStorage存储数据export const removeSession = (name) => {if (!name) return;sessionStorage.removeItem(name);};
解析 URL Params 为对象
function parseParam(url) {const paramsStr = /.+\?(.+)$/.exec(url)[1];const paramsArr = paramsStr.split("&");let paramsObj = {};paramsArr.forEach((param) => {// 处理有 value 的参数if (/=/.test(param)) {// 分割 key 和 valuelet [key, val] = param.split("=");// 解码val = decodeURIComponent(val);// 判断是否转为数字val = /^\d+$/.test(val) ? parseFloat(val) : val;// 如果对象有 key,则添加⼀个值if (paramsObj.hasOwnProperty(key)) {paramsObj[key] = [].concat(paramsObj[key], val);} else {// 如果对象没有这个 key,创建 key 并设置值paramsObj[key] = val;}} else {// 处理没有 value 的参数paramsObj[param] = true;}});return paramsObj;}let url = "http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled";parseParam(url);// {// city: "北京",// enabled: true,// id: [123, 456],// user: "anonymous",// }
获取URL的中参数
/*** @method 获取URL的中参数* @param {*} strUrl*/export const getQueryString = (strUrl) => {let reg = new RegExp("(^|&)" + strUrl + "=([^&]*)(&|$)", "i");let r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配let context = "";if (r != null) context = r[2];reg = null;r = null;return context == null || context == "" || context == "undefined"? "": context;};
时间格式化
/*** @method 时间格式化* @param {string} time* @param {string} format yyyy/mm/dd hh:ii:ss(2019/07/24 09:45:43) yy/m/d hh:ii:ss(19/07/24 09:45:43) yyyy/mm/dd w(2019/07/24 星期三) mm/dd/yyyy(07/24/2019)* @returns*/export const formatTime = (time, format = "yyyy-mm-dd") => {const d = time ? new Date(time) : new Date();const t = (i) => {return (i < 10 ? "0" : "") + i;};const year = d.getFullYear();const month = d.getMonth() + 1;const day = d.getDate();const hour = d.getHours();const minutes = d.getMinutes();const seconds = d.getSeconds();const weekday = d.getDay();return format.replace(/(yy){1,2}|m{1,2}|d{1,2}|h{1,2}|i{1,2}|s{1,2}|w{1,2}/gi,function (r) {switch (r.toUpperCase()) {case "YY":return ("" + year).substr(2);case "YYYY":return year;case "M":return month;case "MM":return t(month);case "D":return day;case "DD":return t(day);case "H":return hour;case "HH":return t(hour);case "I":return minutes;case "II":return t(minutes);case "S":return seconds;case "SS":return t(seconds);case "W":return `星期${["日", "一", "二", "三", "四", "五", "六"][weekday]}`;case "WW":return ["Sunday","Monday","TuesDay","Wednesday","Thursday","Friday","Saturday",][weekday];}});};
防抖
防抖:防止抖动,单位时间内事件触发会被重置,避免事件被误伤触发多次。 代码实现重在清零 clearTimeout。 防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。 业务场景有避免登录按钮多次点击的重复提交。
/*** @description 函数防抖* @param {Function} method 延时调用函数* @param {Number} wait 延迟时长* @param {Boolean} immediate 立即执行选项*/export const Ddebounce = (method, wait, immediate) => {if (typeof method != "function") {throw new TypeError("Expected a function");}let timeout;// Ddebounce函数为返回值// 使用Async/Await处理异步,如果函数异步执行,等待setTimeout执行完,拿到原函数返回值后将其返回// args为返回函数调用时传入的参数,传给methodlet Ddebounce = function (...args) {return new Promise((resolve) => {// 用于记录原函数执行结果let result;// 将method执行时this的指向设为 debounce 返回的函数被调用时的this指向let context = this;// 如果存在定时器则将其清除if (timeout) {clearTimeout(timeout);}// 立即执行需要两个条件,一是immediate为true,二是timeout未被赋值或被置为nullif (immediate) {// 如果定时器不存在,则立即执行,并设置一个定时器,wait毫秒后将定时器置为null// 这样确保立即执行后wait毫秒内不会被再次触发let callNow = !timeout;timeout = setTimeout(() => {timeout = null;}, wait);// 如果满足上述两个条件,则立即执行并记录其执行结果if (callNow) {result = method.apply(context, args);resolve(result);}} else {// 如果immediate为false,则等待函数执行并记录其执行结果// 并将Promise状态置为fullfilled,以使函数继续执行timeout = setTimeout(() => {// args是一个数组,所以使用fn.apply// 也可写作method.call(context, ...args)result = method.apply(context, args);resolve(result);}, wait);}});};// 在返回的 Ddebounce 函数上添加取消方法Ddebounce.cancel = function () {clearTimeout(timeout);timeout = null;};return Ddebounce;};
节流
节流:控制流量,单位时间内事件只能触发一次,与服务器端的限流 (Rate Limit) 类似。 代码实现重在开锁关锁 timer=timeout; timer=null。 节流可以比作过红绿灯,每等一个红灯时间就可以过一批。
/*** @method 节流* @param {*} func* @param {*} delay*/export const Dthrottle = (func, delay) => {let timer = null;return function () {let context = this;let args = arguments;if (!timer) {timer = setTimeout(function () {func.apply(context, args);timer = null;}, delay);}};};
数组扁平化
/*** @method 数组扁平化* @param {*} arry*/export const deepFlatten = (arr) => {return arr.toString().split(",").map((item) => +item);// or// return [].concat(...arr.map(item => (Array.isArray(item) ? deepFlatten(item) : item)));};
判断类型
/*** @method 判断类型* @param {*} obj* @returns*/export const toType = (obj) => {return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();};
html 转义
export const escapeHtml = (str) => {if (!str) return;str = str.replace(/&/g, "&");str = str.replace(/</g, "<");str = str.replace(/>/g, ">");str = str.replace(/“/g, "&quto;");str = str.replace(/'/g, "'");return str;};
等待一定时间后执行
const wait = async milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));
判断对象是否为空
const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object
检查函数是否是promise
// 可先看vue源码实现(不严谨,但是够用)function isDef(v) {return v !== undefined && v !== null;}function isPromise(fn) {return isDef(fn) && typeof fn.then === 'function' && typeof fn.catch === 'function';}console.log(isPromise(new Promise())); // true// graphql-js 的实现方式function isPromise_graphql(fn) {return Boolean(fn && typeof fn.then === 'function');}// 利用 instanceoffunction isPromise_instanceof(fn) {return fn instanceof Promise;}// 利用 prototypefunction isPromise_prototype(fn) {return fn && Object.prototype.toString.call(fn) === "[object Promise]";}
检查函数是否是一个生成器
const test = function*() {yield undefined;};console.log(x.constructor.name === 'GeneratorFunction'); // true// 或者const GeneratorFunction = function*() {yield undefined;}.constructor;console.log(test instanceof GeneratorFunction); // true// 需要注意foo = test.bind(bar);console.log(foo instanceof GeneratorFunction); // false
