收集一些可以提升代码执行效率的技巧,不断更新中~
惰性函数
举个栗子 - 复制文本
js
function copyText(text) {
if (navigator.clipboard) {
navigator.clipboard.writeText(text)
} else {
const input = document.createElement('input')
input.setAttribute('value', text)
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
}
}
这是一个复制文本方法,兼容不同浏览器API时,其实只需要判断一次即可,没必要每次执行都判断一次是否支持该方法,因为浏览器环境是不会在使用过程中发生变化的。修改后如下:
js
function copyText(text) {
if (navigator.clipboard) {
copyText = (text) => {
navigator.clipboard.writeText(text)
}
} else {
copyText = (text) => {
const input = document.createElement('input')
input.setAttribute('value', text)
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
}
}
copyText(text)
}
修改为惰性函数后,在第一次调用copyText
函数时就被修改了函数体,之后再调用就不会再判断是否支持,提升效率
参数归一化
举个栗子 - 日期格式化
写一个日期格式化方法format
,可能需要如下多种传参
js
function format() {}
// 2024-4-16
format(new Date(), 'date')
// 2024-4-16 10:5:46
format(new Date(), 'datetime')
// 2024-04-16
format(new Date(), 'date', true)
// 2024-04-16 10:05:46
format(new Date(), 'datetime', true)
// 2024年04月16日 10:05
format(new Date(), 'yyyy年MM月dd日 HH:mm', true)
// 2024年04月16日 10:05:46.565
format(new Date(), 'yyyy年MM月dd日 HH:mm:ss.ms', true)
// 今年
format(new Date(), (dateInfo) => {
const { year } = dateInfo;
const thisYear = new Date().getFullYear();
if (year < thisYear) {
return `${thisYear - year}年前`;
} else if (year > thisYear) {
return `${year - thisYear}年后`;
} else {
return '今年';
}
})
我们可以对第二个参数进行归一化处理,找到最复杂的那个参数function
,其它参数都向这个格式进行归一化,代码实现如下:
js
function _formatNormalize(formatter) {
if (typeof formatter === 'function') return formatter;
if (typeof formatter !== 'string') throw new Error('formatter must be a string or a function');
if (formatter === 'date') {
formatter = 'yyyy-MM-dd';
} else if (formatter === 'datetime') {
formatter = 'yyyy-MM-dd HH:mm:ss';
}
return (dateInfo) => {
const { yyyy, MM, dd, HH, mm, ss, ms } = dateInfo;
return formatter
.replace(/yyyy/g, yyyy)
.replace(/MM/g, MM)
.replace(/dd/g, dd)
.replace(/HH/g, HH)
.replace(/mm/g, mm)
.replace(/ss/g, ss)
.replace(/ms/g, ms);
};
}
function format(date, formatter, isPad = false) {
formatter = _formatNormalize(formatter);
function _pad(value, length) {
return isPad ? (value + '').padStart(length, '0') : value.toString();
}
const dateInfo = {
year: date.getFullYear(),
month: date.getMonth() + 1,
day: date.getDate(),
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds(),
milliseconds: date.getMilliseconds(),
};
dateInfo.yyyy = _pad(dateInfo.year, 4);
dateInfo.MM = _pad(dateInfo.month, 2);
dateInfo.dd = _pad(dateInfo.day, 2);
dateInfo.HH = _pad(dateInfo.hours, 2);
dateInfo.mm = _pad(dateInfo.minutes, 2);
dateInfo.ss = _pad(dateInfo.seconds, 2);
dateInfo.ms = _pad(dateInfo.milliseconds, 3);
return formatter(dateInfo);
}
// 可能调用的方式
console.log(format(new Date(), 'date'));
console.log(format(new Date(), 'datetime'));
console.log(format(new Date(), 'date', true));
console.log(format(new Date(), 'datetime', true));
console.log(format(new Date(), 'yyyy年MM月dd日 HH:mm', true));
console.log(format(new Date(), 'yyyy年MM月dd日 HH:mm:ss.ms', true));
console.log(
format(new Date(), (dateInfo) => {
const { year } = dateInfo;
const thisYear = new Date().getFullYear();
if (year < thisYear) {
return `${thisYear - year}年前`;
} else if (year > thisYear) {
return `${year - thisYear}年后`;
} else {
return '今年';
}
})
);