Skip to content

常见工具函数

提示

推荐使用各种工具库,如:

防抖

防抖:函数触发后,等待一段时间,再运行函数,如果这段时间内事件再次被触发,则重新计时。

巧记:回城

使用场景:输入框实时搜索,窗口大小调整 …… 等等 短时间内高频触发 的场景。

ts
export function debounce(fn: Function, delay: number = 500) {
  let timer: ReturnType<typeof setTimeout>
  return function (...args: any[]) {
    clearTimeout(timer)
    timer = setTimeout(() => {
      // @ts-ignore
      fn.apply(this, args)
    }, delay)
  }
}
使用说明

在 vue 中使用 debounce

vue
<script setup>
import { debounce } from '@/utils'

let value = ref('')

// 不生效
function handelKeyUp2(args) {
  console.log('请求url', value.value, args)
}

// 生效
const handelKeyUp = debounce(function (args) {
  console.log('请求url', value.value, args)
}, 300)
</script>

<template>
  <!-- 不生效 -->
  <el-input v-model="value" @keyup="debounce(handelKeyUp2, 300)"></el-input>

  <!-- 生效 -->
  <el-input v-model="value" @keyup="handelKeyUp"></el-input>
</template>

节流

节流:在一定时间间隔中,只执行一次函数。

巧记:技能 cd

使用场景:滚动事件,鼠标移动 …… 等等 高频触发 的场景。

ts
export function throttle(fn: Function, wait: number = 1000) {
  let lastTime = 0
  return function (...args: any[]) {
    const now = Date.now()
    if (lastTime === 0 || now - lastTime > wait) {
      // @ts-ignore
      fn.apply(this, args)
      lastTime = now
    }
  }
}

柯里化

创建一个函数,该函数接收 func 的参数,要么调用 func 返回的结果,如果 func 所需参数已经提供,则直接返回 func 所执行的结果。或返回一个函数,接受余下的 func 参数的函数,可以使用 func.length 强制需要累积的参数个数。

js
function curry(fn, ...args) {
  return function (...args2) {
    const allArgs = args.concat(args2)
    if (allArgs.length >= fn.length) {
      return fn.apply(this, allArgs)
    } else {
      return curry(fn, ...allArgs)
    }
  }
}
js
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args)
    } else {
      return function (...args2) {
        return curried.apply(this, args.concat(args2))
      }
    }
  }
}
示例
js
const sum = (a, b, c, d) => a + b + c + d

console.log(curry(sum)(1)(2)(3)(4)) // 输出 10
console.log(curry(sum)(1, 2)(3, 4)) // 输出 10
console.log(curry(sum)(1, 2, 3)(4)) // 输出 10
console.log(curry(sum)(1, 2, 3, 4)) // 输出 10

深拷贝

js
function deepClone(target) {
  const res = JSON.stringify(target)
  return JSON.parse(res)
}

金额格式化

js
function formatMoney(money: number | string) {
  const a = parseFloat(money.toString())
  return a.toLocaleString('zh-CN', { style: 'currency', currency: 'CNY' })
}

// =>
console.log(formatMoney(123456789)) // ¥123,456,789.00
console.log(formatMoney(123456789.1234)) // ¥123,456,789.12

数字格式化

ts
function formatNum(num: number | string) {
  const a = num.toString()
  if (a.indexOf('.') === -1) {
    return a.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
  }
  return a.replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}

// =>
console.log(formatNum(123456789)) // 123,456,789
console.log(formatNum(123456789.1234)) // 123,456,789.1234

日期格式化

ts
function formatDate(date: Date = new Date(), rule: string = 'YYYY-MM-DD HH:mm:ss') {
  let fmt = rule
  fmt = fmt.replace(/(Y+)/, date.getFullYear().toString())
  fmt = fmt.replace(/(M+)/, (date.getMonth() + 1).toString().padEnd(2, '0'))
  fmt = fmt.replace(/(D+)/, date.getDate().toString().padEnd(2, '0'))
  fmt = fmt.replace(/(H+)/, date.getHours().toString().padStart(2, '0'))
  fmt = fmt.replace(/(m+)/, date.getMinutes().toString().padStart(2, '0'))
  fmt = fmt.replace(/(s+)/, date.getSeconds().toString().padStart(2, '0'))
  return fmt
}

基于 MIT 许可发布