• 常用的工具函数助力JavaScript高效开发


     

     

    前言

    日常开发中,面对各种不同的需求,我们经常会用到以前开发过的一些工具函数,把这些工具函数收集起来,将大大提高我们的开发效率。

    1、校验数据类型

    export const typeOf = function(obj) {
      return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
    }

    示例:

    typeOf('树哥')  // string
    typeOf([])  // array
    typeOf(new Date())  // date
    typeOf(null// null
    typeOf(true// boolean
    typeOf(() => { }) // function

    2、防抖

    export const debounce = (() => {
      let timer = null
      return (callback, wait = 800) => {
        timer&&clearTimeout(timer)
        timer = setTimeout(callback, wait)
      }
    })()

    示例:

    如 vue 中使用

    methods: {
      loadList() {
        debounce(() => {
          console.log('加载数据')
        }, 500)
      }
    }

    3、节流

    export const throttle = (() => {
      let last = 0
      return (callback, wait = 800) => {
        let now = +new Date()
        if (now - last > wait) {
          callback()
          last = now
        }
      }
    })()

    4、手机号脱敏

    export const hideMobile = (mobile) => {
      return mobile.replace(/^(\d{3})\d{4}(\d{4})$/"$1****$2")
    }

    5、开启全屏

    export const launchFullscreen = (element) => {
      if (element.requestFullscreen) {
        element.requestFullscreen()
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen()
      } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen()
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullScreen()
      }
    }

    6、关闭全屏

    export const exitFullscreen = () => {
      if (document.exitFullscreen) {
        document.exitFullscreen()
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen()
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen()
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen()
      }
    }

    7、大小写转换

    参数:

    • str 待转换的字符串
    • type 1-全大写 2-全小写 3-首字母大写
    export const turnCase = (strtype) => {
      switch (type) {
        case 1:
          return str.toUpperCase()
        case 2:
          return str.toLowerCase()
        case 3:
          //return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
          return str[0].toUpperCase() + str.substring(1).toLowerCase()
        default:
          return str
      }
    }

    示例:

    turnCase('vue', 1// VUE
    turnCase('REACT', 2// react
    turnCase('vue', 3// Vue

    8、解析URL参数

    export const getSearchParams = () => {
      const searchPar = new URLSearchParams(window.location.search)
      const paramsObj = {}
      for (const [key, value] of searchPar.entries()) {
        paramsObj[key] = value
      }
      return paramsObj
    }

    示例:

    // 假设目前位于 https://****com/index?id=154513&age=18;
    getSearchParams(); // {id"154513", age: "18"}

    9、判断手机是Andoird还是IOS

    /** 
     * 1: ios
     * 2: android
     * 3: 其它
     */
    export const getOSType=() => {
      let u = navigator.userAgent, app = navigator.appVersion;
      let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
      let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
      if (isIOS) {
        return 1;
      }
      if (isAndroid) {
        return 2;
      }
      return 3;
    }

    10、数组对象根据字段去重

    参数:

    • arr 要去重的数组
    • key 根据去重的字段名
    export const uniqueArrayObject = (arr = [], key = 'id') => {
      if (arr.length === 0return
      let list = []
      const map = {}
      arr.forEach((item) => {
        if (!map[item[key]]) {
          map[item[key]] = item
        }
      })
      list = Object.values(map)
      return list
    }

    示例:

    const responseList = [
        { id: 1, name: '树哥' },
        { id: 2, name: '黄老爷' },
        { id: 3, name: '张麻子' },
        { id: 1, name: '黄老爷' },
        { id: 2, name: '张麻子' },
        { id: 3, name: '树哥' },
        { id: 1, name: '树哥' },
        { id: 2, name: '黄老爷' },
        { id: 3, name: '张麻子' },
    ]
    uniqueArrayObject(responseList, 'id')
    // [{ id: 1, name: '树哥' },{ id: 2, name: '黄老爷' },{ id: 3, name: '张麻子' }]

    11、滚动到页面顶部

    export const scrollToTop = () => {
      const height = document.documentElement.scrollTop || document.body.scrollTop;
      if (height > 0) {
        window.requestAnimationFrame(scrollToTop);
        window.scrollTo(0, height - height / 8);
      }
    }

    12、滚动到元素位置

    export const smoothScroll = element =>{
        document.querySelector(element).scrollIntoView({
            behavior: 'smooth'
        });
    };

    示例:

    smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素

    13、uuid

    export const uuid = () => {
      const temp_url = URL.createObjectURL(new Blob())
      const uuid = temp_url.toString()
      URL.revokeObjectURL(temp_url) //释放这个url
      return uuid.substring(uuid.lastIndexOf('/') + 1)
    }

    示例:

    uuid() // a640be34-689f-4b98-be77-e3972f9bffdd

    不过要吐槽一句的是,uuid一般应由后端来进行生成

    14、金额格式化

    参数:

    • {number} number:要格式化的数字
    • {number} decimals:保留几位小数
    • {string} dec_point:小数点符号
    • {string} thousands_sep:千分位符号
    export const moneyFormat = (number, decimals, dec_point, thousands_sep) => {
      number = (number + '').replace(/[^0-9+-Ee.]/g'')
      const n = !isFinite(+number) ? 0 : +number
      const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
      const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
      const dec = typeof dec_point === 'undefined' ? '.' : dec_point
      let s = ''
      const toFixedFix = function(n, prec) {
        const k = Math.pow(10, prec)
        return '' + Math.ceil(n * k) / k
      }
      s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
      const re = /(-?\d+)(\d{3})/
      while (re.test(s[0])) {
        s[0] = s[0].replace(re, '$1' + sep + '$2')
      }
      if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
      }
      return s.join(dec)
    }

    示例:

    moneyFormat(10000000// 10,000,000.00
    moneyFormat(100000003, '.', '-') // 10-000-000.000

    15、存储操作

    class MyCache {
      constructor(isLocal = true) {
        this.storage = isLocal ? localStorage : sessionStorage
      }
      setItem(key, value) {
        if (typeof (value) === 'object') value = JSON.stringify(value)
        this.storage.setItem(key, value)
      }
      getItem(key) {
        try {
          return JSON.parse(this.storage.getItem(key))
        } catch (err) {
          return this.storage.getItem(key)
        }
      }
      removeItem(key) {
        this.storage.removeItem(key)
      }
      clear() {
        this.storage.clear()
      }
      key(index) {
        return this.storage.key(index)
      }
      length() {
        return this.storage.length
      }
    }
    const localCache = new MyCache()
    const sessionCache = new MyCache(false)
    export { localCache, sessionCache }

    示例:

    localCache.getItem('user')
    sessionCache.setItem('name','树哥')
    sessionCache.getItem('token')
    localCache.clear()

    16、下载文件

    参数:

    • api 接口
    • params 请求参数
    • fileName 文件名
    const downloadFile = (api, params, fileName, type = 'get') => {
      axios({
        methodtype,
        url: api,
        responseType'blob'
        params: params
      }).then((res) => {
        let str = res.headers['content-disposition']
        if (!res || !str) {
          return
        }
        let suffix = ''
        // 截取文件名和文件类型
        if (str.lastIndexOf('.')) {
          fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
          suffix = str.substring(str.lastIndexOf('.'), str.length)
        }
        //  如果支持微软的文件下载方式(ie10+浏览器)
        if (window.navigator.msSaveBlob) {
          try {
            const blobObject = new Blob([res.data]);
            window.navigator.msSaveBlob(blobObject, fileName + suffix);
          } catch (e) {
            console.log(e);
          }
        } else {
          //  其他浏览器
          let url = window.URL.createObjectURL(res.data)
          let link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.setAttribute('download', fileName + suffix)
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          window.URL.revokeObjectURL(link.href);
        }
      }).catch((err) => {
        console.log(err.message);
      })
    }`

    使用:

    downloadFile('/api/download', {id}, '文件名')

    17、时间操作

    关于时间操作,没必要自己再写一大串代码了,强烈推荐使用 day.js[2]

    Day.js 是一个仅 2kb 大小的轻量级 JavaScript 时间日期处理库,下载、解析和执行的JavaScript更少,为代码留下更多的时间。

    18、深拷贝

    export const clone = parent => {
      // 判断类型
      const isType = (obj, type) => {
        if (typeof obj !== "object"return false;
        const typeString = Object.prototype.toString.call(obj);
        let flag;
        switch (type) {
          case "Array":
            flag = typeString === "[object Array]";
            break;
          case "Date":
            flag = typeString === "[object Date]";
            break;
          case "RegExp":
            flag = typeString === "[object RegExp]";
            break;
          default:
            flag = false;
        }
        return flag;
      };
      // 处理正则
      const getRegExp = re => {
        var flags = "";
        if (re.global) flags += "g";
        if (re.ignoreCase) flags += "i";
        if (re.multiline) flags += "m";
        return flags;
      };
      // 维护两个储存循环引用的数组
      const parents = [];
      const children = [];
      const _clone = parent => {
        if (parent === nullreturn null;
        if (typeof parent !== "object"return parent;
        let child, proto;
        if (isType(parent, "Array")) {
          // 对数组做特殊处理
          child = [];
        } else if (isType(parent, "RegExp")) {
          // 对正则对象做特殊处理
          child = new RegExp(parent.sourcegetRegExp(parent));
          if (parent.lastIndex) child.lastIndex = parent.lastIndex;
        } else if (isType(parent, "Date")) {
          // 对Date对象做特殊处理
          child = new Date(parent.getTime());
        } else {
          // 处理对象原型
          proto = Object.getPrototypeOf(parent);
          // 利用Object.create切断原型链
          child = Object.create(proto);
        }
        // 处理循环引用
        const index = parents.indexOf(parent);
        if (index != -1) {
          // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
          return children[index];
        }
        parents.push(parent);
        children.push(child);
        for (let i in parent) {
          // 递归
          child[i] = _clone(parent[i]);
        }
        return child;
      };
      return _clone(parent);
    };

    此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。

    如果确实想要完备的深拷贝,推荐使用 lodash 中的 cloneDeep 方法。

    19、模糊搜索

    参数:

    • list 原数组
    • keyWord 查询的关键词
    • attribute 数组需要检索属性
    export const fuzzyQuery = (list, keyWord, attribute = 'name') => {
      const reg = new RegExp(keyWord)
      const arr = []
      for (let i = 0; i < list.length; i++) {
        if (reg.test(list[i][attribute])) {
          arr.push(list[i])
        }
      }
      return arr
    }

    示例:

    const list = [
      { id1, name: '树哥' },
      { id2, name: '黄老爷' },
      { id3, name: '张麻子' },
      { id4, name: '汤师爷' },
      { id5, name: '胡万' },
      { id6, name: '花姐' },
      { id7, name: '小梅' }
    ]
    fuzzyQuery(list, '树''name'// [{id: 1, name: '树哥'}]

    20、遍历树节点

    export const foreachTree = (data, callback, childrenName = 'children') => {
      for (let i = 0; i < data.length; i++) {
        callback(data[i])
        if (data[i][childrenName] && data[i][childrenName].length > 0) {
          foreachTree(data[i][childrenName], callback, childrenName)
        }
      }
    }

    示例:

    假设我们要从树状结构数据中查找 id 为 9 的节点

    const treeData = [{
      id: 1,
      label: '一级 1',
      children: [{
        id: 4,
        label: '二级 1-1',
        children: [{
          id: 9,
          label: '三级 1-1-1'
        }, {
          id: 10,
          label: '三级 1-1-2'
        }]
      }]
     }, {
      id: 2,
      label: '一级 2',
      children: [{
        id: 5,
        label: '二级 2-1'
      }, {
        id: 6,
        label: '二级 2-2'
      }]
      }, {
        id: 3,
        label: '一级 3',
        children: [{
          id: 7,
          label: '二级 3-1'
        }, {
          id: 8,
          label: '二级 3-2'
        }]
    }],
    let result
    foreachTree(data, (item) => {
      if (item.id === 9) {
        result = item
      }
    })
    console.log('result', result)  // {id: 9,label: "三级 1-1-1"}   

     

  • 相关阅读:
    PDF文件怎么解密?教你三种解密的方法
    【微服务部署】04-ForwardedHeaders
    云和恩墨大讲堂 x openGauss Meetup x 鲲鹏生态孵化营(上海站)圆满落幕
    C. Water the Trees Educational Codeforces Round 126 (Rated for Div. 2)
    十五、环境变量和代理跨域及api的定义
    servlet如何获取PUT和DELETE请求的参数
    ATFX汇市:美国9月PCE数据来袭,高通胀问题或已不构成威胁
    Scala
    GBase 8c 创建用户/角色 示例二
    取得PMP证书需要多长时间?
  • 原文地址:https://www.cnblogs.com/houxianzhou/p/16669842.html