16进制随机颜色
let color = '#'+Math.random().toString(16).slice(-6)
类型判断工具函数
function isType(target, type) { let targetType = Object.prototype.toString.call(target).slice(8, -1).toLowerCase() type = type.toLowerCase() return targetType === type }
isType([],'array') //true
正则匹配两个字符间的内容
第一种:断言匹配(这种方式在ie浏览器不适应)
let str = '订阅项目:{{phrase1.DATA}}
更新内容:{{thing_2.DATA}}
提示说明:{{thing3.DATA}}'
let res = str.match(/(?<={{).*?(?=}})/g) // ["phrase1.DATA", "thing_2.DATA", "thing3.DATA"]
x(?=y): 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言,y不作为匹配结果的一部分
(?<=y)x:匹配'x'仅仅当'x'前面是'y'.这种叫做后行断言,y不作为匹配结果的一部分
第二种:组匹配
let str = '订阅项目:{{phrase1.DATA}} 更新内容:{{thing_2.DATA}} 提示说明:{{thing3.DATA}}' let arr = [] str.replace(/{{(.*?)}}/g,($0,$1)={arr.push($1)})
replace第二个参数可以设置为回调函数
函数第一个参数为正则匹配到的字符串
函数第二个参数为组匹配的内容(即圆括号的内容)
简洁的设置默认参数
if(!arr){ arr = [] } arr.push(1) //可以这样写 (arr && (arr=[])).push(1)
reduce会更简洁
filter和map的组合使用可能很多人都会使用过,但是这样会进行两次遍历操作。可以使用reduce遍历一次完成同样的操作。
reduce接受一个回调函数和一个默认值。
回调函数接受两个参数,prev是上次返回值,curr是当前遍历值。在第一次遍历时,prev为默认值,每次遍历返回的prev都会在下一个遍历中取到。reduce因此也被叫做”累加函数“。
let people = [{name:'Joe',age:18},{name:'Mike',age:19},{name:'Jack',age:20}] people.fliter(p=>p.age < 20).map(p=>p.name) //可以这样写 people.reduce((prev,curr)=>{ if(age<20){ prev.push(curr.name) } return prev },[])
策略模式
使用策略模式来代替一堆的 if...else,让代码看起来更简洁
if(type == = 'content'){ getContent() }else if(type === 'hot'){ getHot() }else if(type === 'rank'){ getRank() } ... //可以这样写 let action = { content: getContent, hot: getHot, rank: getRank, .... } action[type]()
JSON.stringify的其他参数
let str = {a:1,b:2,c:3} //过滤 JSON.stringify(str, ['a']) //"{"a":1}" //格式化 JSON.stringify(str, null, 2) /* "{ "a": 1, "b": 2, "c": 3 }" */
获取月份的最后一天
new Date('2019','2',0).getDate()
优雅处理await异常
一般处理await会使用try catch,但这样的代码结构看起来会显得冗余不够简洁。我们可以通过Error-first模式来处理异常,该模式参考node.js处理回调模式
//to.js export default function to(promise){ return promise .then(res=>[null,res]) .catch(err=>[err]) }
import to from './to.js' async function foo(){ let err,res; [err, res] = await to(promiseTask) if(err) throw err }
获取当天凌晨12点时间
new Date(new Date().toLocaleDateString()).getTime()
验证数组项
every方法接受一个回调函数,函数内需要返回验证规则(布尔值)。
every会根据回调函数返回的规则去验证每一项,只有全部通过规则,才会返回true。some方法恰好与every方法相反,some方法只需要一项通过,即返回true。
let wordData = ['', 0, undefined, null, false] wordData.every(Boolean) // false
科学计数
比如我们需要用毫秒数来表达一天的时间即86400000,为了简洁可以使用科学计数
8.64e7 //86400000
快速生成一周的时间
Array构造函数若只传数字作为参数会生成对应长度的数组,但这种数组只是拥有长度属性并没有实际内容,需要扩展数组为项设置初始值,这样使用遍历方法才能够拿到想要的数据
[...Array(7)].map((j,i)=> new Date(Date.now()+i*8.64e7).toLocaleDateString()) // ["2019/12/25", "2019/12/26", "2019/12/27", "2019/12/28", "2019/12/29", "2019/12/30", "2019/12/31"]
灵活的日期格式化函数
第一个参数接受时间戳,第二个函数接受格式化字符串。重点在于第二个参数,可以根据使用者输入的格式来应对多种需求。
function startFillZero(num){ return num < 10 ? '0'+num : num } function formatDate(timestamp=Date.now(), format='Y-M-D h:m'){ if((timestamp).toString().length == 10){ timestamp = timestamp * 1000 } let date = new Date(timestamp) let dateObj = { Y: date.getFullYear(), M: date.getMonth()+1, D: date.getDate(), h: date.getHours(), m: date.getMinutes(), s: date.getSeconds() } let res = format .replace('Y',dateObj.Y) .replace('M',dateObj.M) .replace('D',dateObj.D) .replace('h',startFillZero(dateObj.h)) .replace('m',startFillZero(dateObj.m)) .replace('s',startFillZero(dateObj.s)) return res }
正则验证密码强度
const strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})"); const mediumRegex = new RegExp("^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})");
(?=.*[a-z]) | 该字符串必须包含至少1个小写字母字符 |
(?=.*[A-Z]) | 该字符串必须包含至少1个大写字母字符 |
(?=.*[0-9]) | 该字符串必须至少包含1个数字字符 |
(?=.[!@#$%^&]) | 该字符串必须至少包含一个特殊字符,但是为了避免冲突,转义了 RegEx 保留字符。 |
(?=.{8,}) | 字符串必须至少是八个字符。 |
对象属性剔除
function omit(object, props=[]){ let res = {} Object.keys(object).forEach(key=>{ if(props.includes(key) === false){ res[key] = typeof object[key] === 'object' && object[key] !== null ? JSON.parse(JSON.stringify(object[key])): object[key] } }) return res }
使用
let obj = { name: 'joe', age: 18, like: ['apple'] } omit(obj, ['like']) // {name: 'joe', age: 18}
正则匹配域名
'https://bbb.aaa.juejin.im/post/5ea6950ee51d4546ef36bae5'.match(/((([A-Za-z]{3,9}:(?://)?)(?:[-;:&=+$,w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=+$,w]+@)[A-Za-z0-9.-]+)((?:/[+~%/.w-_]*)???(?:[-+=&;%@.w_]*)#?(?:[w]*))?)/)[0]
'https://bbb.aaa.juejin.im/post/5ea6950ee51d4546ef36bae5'.match(/^(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.,?'\+&%$#=~_-]+))*$/)[0]
正则匹配网址信息
const parseUrl = /^(?:([A-Za-z]+):)?(/{0,3})([0-9.-A-Za-z]+)(?::(d+))?(?:/([^?#]*))?(?:?([^#]*))?(?:#(.*))?$/;
Intl
es5中有一个用于国际化的api,可用来做日期和数字等的格式化
Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits: 2 }).format(1232142.123123); // "¥1,232,142.12"
不定时更新~