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 '今年';
    }
  })
);
相关推荐
IT_陈寒几秒前
Vite静态资源路径这个大坑害我调了一下午
前端·人工智能·后端
狗哥哥6 分钟前
分享下我的读书清单
前端
合天网安实验室18 分钟前
Log4J2 FilteredObjectInputStream RCE 漏洞分析
前端·黑客
两点王爷23 分钟前
使用 GeoServer 发布 SHP 数据并在前端页面加载显示
前端
lhldsg31 分钟前
全民健身解决方案软件开发实战:从架构设计到部署指南
java·前端·数据库·小程序
四六的六32 分钟前
让 AI 自己去点后台页面,它把我们的库存点没了
前端·人工智能·agent·个人开发·ai编程·ai产品·ai前端
两点王爷33 分钟前
Java 与前端加载 MVT 数据:从服务端切片到浏览器渲染
java·前端·状态模式
小码过河.1 小时前
oceanbase中zone和observer、分区表之间关系
前端·数据库·oceanbase
平头哥技术团队2 小时前
Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页
开发语言·前端·html·html5
代码青铜z2 小时前
不会写代码做小程序,模板开发和AI 编程靠谱吗?创业前先看这 5 件事
前端