js代码优化技巧

收集一些可以提升代码执行效率的技巧,不断更新中~

惰性函数

举个栗子 - 复制文本

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 '今年';
    }
  })
);
相关推荐
2503_9284115633 分钟前
12.4 axios的二次封装-深拷贝
前端·javascript·vue.js
你真的可爱呀4 小时前
uniapp+vue3项目中的常见报错情况以及解决方法
前端·vue.js·uni-app
差点GDP7 小时前
模拟请求测试 Fake Rest API Test
前端·网络·json
酒尘&8 小时前
Hook学习-上篇
前端·学习·react.js·前端框架·react
houyhea9 小时前
从香港竹脚手架到前端脚手架:那些"借来"的发展智慧与安全警示
前端
哈哈~haha9 小时前
Step 14: Custom CSS and Theme Colors 自定义CSS类
前端·css·ui5
Ndmzi9 小时前
Matlab编程技巧:自定义Simulink菜单(理解补充)
前端·javascript·python
勇气要爆发9 小时前
物种起源—JavaScript原型链详解
开发语言·javascript·原型模式
我命由我123459 小时前
VSCode - VSCode 修改文件树缩进
前端·ide·vscode·前端框架·编辑器·html·js
SoaringHeart10 小时前
Flutter组件封装:验证码倒计时按钮 TimerButton
前端·flutter