Jie's Blog Jie's Blog
首页
  • JavaScript

    • 项目常用的JavaScript代码片段
  • Html

    • Html标签介绍
  • Css

    • elementui打包后字体图乱码解决方法
  • 龙虾(OpenClaw)搭建指南
  • 如何只展示当前地图视区的定位mark
  • npm私有仓库搭建
  • 植物大战僵尸杂交版v2.1安装教程
关于
资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

抬手一个div

前端切图仔
首页
  • JavaScript

    • 项目常用的JavaScript代码片段
  • Html

    • Html标签介绍
  • Css

    • elementui打包后字体图乱码解决方法
  • 龙虾(OpenClaw)搭建指南
  • 如何只展示当前地图视区的定位mark
  • npm私有仓库搭建
  • 植物大战僵尸杂交版v2.1安装教程
关于
资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

    • 项目常用的 JavaScript 代码片段
    • TypeScript

    • Vue

    • React

    • 前端
    • JavaScript
    Jie
    2024-06-19
    目录

    项目常用的 JavaScript 代码片段

    # 项目常用的 JavaScript 代码片段

    # 1. 下载一个 excel 文档

    同时适用于 word,ppt 等浏览器不会默认执行预览的文档,也可以用于下载后端接口返回的流数据。

    //下载一个链接
    const download = (link, name) => {
      //如果没有提供名字,从给的Link中截取最后一坨
      if (!name) name = link.slice(link.lastIndexOf('/') + 1)
      let eleLink = document.createElement('a')
      eleLink.download = name
      eleLink.style.display = 'none'
      eleLink.href = link
      document.body.appendChild(eleLink)
      eleLink.click()
      document.body.removeChild(eleLink)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    使用方式

    download('http://111.229.14.189/file/1.xlsx')
    download('http://111.229.14.189/gk-api/util/download?file=1.jpg')
    download('http://111.229.14.189/gk-api/util/download?file=1.mp4')
    
    1
    2
    3

    # 2. 在浏览器中自定义下载一些内容

    场景:下载一些 DOM 内容,下载一个 JSON 文件

    /**
     * 浏览器下载静态文件
     * @param {String} name 文件名
     * @param {String} content 文件内容
     */
    const downloadFile = (name, content) => {
      if (typeof name == 'undefined') throw new Error('The first parameter name is a must')
      if (typeof content == 'undefined') throw new Error('The second parameter content is a must')
      if (!(content instanceof Blob)) content = new Blob([content])
      const link = URL.createObjectURL(content)
      // 调用方法1
      download(link, name)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    使用方式

    downloadFile('1.txt', 'lalalallalalla')
    downloadFile('1.json', JSON.stringify({ name: 'hahahha' }))
    
    1
    2

    # 3. 提供一个图片链接,点击下载

    图片、pdf 等文件,浏览器会默认执行预览,不能调用 download 方法进行下载,需要先把图片、pdf 等文件转成 blob,再调用 download 方法进行下载,转换的方式是使用 axios 请求对应的链接。

    //可以用来下载浏览器会默认预览的文件类型,例如mp4,jpg等
    import axios from 'axios'
    //提供一个link,完成文件下载
    const downloadByLink = (link, fileName) => {
      axios
        .request({
          url: link,
          responseType: 'blob', //关键代码,让axios把响应改成blob
        })
        .then((res) => {
          const link = URL.createObjectURL(res.data)
          // 调用方法1
          download(link, fileName)
        })
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    使用方式

    downloadByLink('http://xxx.com/xxx.ppt')
    
    1

    # 4. 防抖

    在一定时间间隔内,多次调用一个方法,只会执行一次。 这个方法的实现是从 Lodash 库中 copy 的。

    /**
     *
     * @param {*} func 要进行debouce的函数
     * @param {*} wait 等待时间,默认500ms
     * @param {*} immediate 是否立即执行
     */
    const debounce = (func, wait = 500, immediate = false) => {
      let timeout
      return function () {
        let context = this
        let args = arguments
        if (timeout) clearTimeout(timeout)
        if (immediate) {
          // 如果已经执行过,不再执行
          let callNow = !timeout
          timeout = setTimeout(function () {
            timeout = null
          }, wait)
          if (callNow) func.apply(context, args)
        } else {
          timeout = setTimeout(function () {
            func.apply(context, args)
          }, wait)
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    使用方式

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <input id="input" />
        <script>
          function onInput() {
            console.log('1111')
          }
          const debounceOnInput = debounce(onInput)
          // 在Input中输入,多次调用只会在调用结束之后,等待500ms触发一次
          document.getElementById('input').addEventListener('input', debounceOnInput)
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    如果第三个参数immediate传 true,则会立即执行一次调用,后续的调用不会在执行,可以自己在代码中试一下

    # 5. 节流

    多次调用方法,按照一定的时间间隔执行。 这个方法的实现也是从 Lodash 库中 copy 的。

    /**
     * 节流,多次触发,间隔时间段执行
     * @param {Function} func
     * @param {Int} wait
     * @param {Object} options
     */
    const throttle = (func, wait = 500, options) => {
      let timeout, context, args
      let previous = 0
      if (!options) options = { leading: false, trailing: true }
      let later = function () {
        previous = options.leading === false ? 0 : new Date().getTime()
        timeout = null
        func.apply(context, args)
        if (!timeout) context = args = null
      }
      const throttled = function () {
        let now = new Date().getTime()
        if (!previous && options.leading === false) previous = now
        let remaining = wait - (now - previous)
        context = this
        args = arguments
        if (remaining <= 0 || remaining > wait) {
          if (timeout) {
            clearTimeout(timeout)
            timeout = null
          }
          previous = now
          func.apply(context, args)
          if (!timeout) context = args = null
        } else if (!timeout && options.trailing !== false) {
          timeout = setTimeout(later, remaining)
        }
      }
      return throttled
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    第三个参数还有点复杂,options

    • leading,函数在每个等待时延的开始被调用,默认值为false
    • trailing,函数在每个等待时延的结束被调用,默认值是true
    可以根据不同的值来设置不同的效果:
    • leading-false,trailing-true:默认情况,即在延时结束后才会调用函数
    • leading-true,trailing-true:在延时开始时就调用,延时结束后也会调用
    • leading-true, trailing-false:只在延时开始时调用
    使用方式
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <input id="input" />
        <script>
          function onInput() {
            console.log('1111')
          }
          const throttleOnInput = throttle(onInput)
          // 在Input中输入,每隔500ms执行一次代码
          document.getElementById('input').addEventListener('input', throttleOnInput)
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # 6. cleanObject

    去除对象中 value 为空(null,undefined,'')的属性 使用场景是:接口传参某个字段为空剔除不传。

    const cleanObject = (object) => {
      if (!object) return {}
      let result = {}
      Object.keys(object).forEach((key) => {
        const value = object[key]
        if (value) result = { ...result, [key]: value }
      })
      return result
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    使用方式

    const newObj = cleanObject({
      name: '',
      pageSize: 10,
      page: 1,
    })
    console.log('res', res) // 输出{ page: 1, pageSize: 10 }
    
    1
    2
    3
    4
    5
    6

    # 7. 获取文件后缀名

    使用场景:上传文件判断后缀名

    /**
     * 获取文件后缀名
     * @param {String} fileName
     */
    const getExt = (fileName) => {
      if (typeof fileName == 'string') return fileName.split('.').pop().toLowerCase()
      throw new Error('fileName must be a string type')
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    使用方式

    getExt('1.mp4') // -> mp4
    
    1

    # 8. 复制内容到剪贴板

    /**
     *原理:
     *创建一个textare元素并调用select()方法选中
     *document.execCommand('copy')方法,拷贝当前选中内容到剪贴板。
     */
    const copyToBoard = (value) => {
      const element = document.createElement('textarea')
      document.body.appendChild(element)
      element.value = value
      element.select()
      if (document.execCommand('copy')) {
        document.execCommand('copy')
        document.body.removeChild(element)
        return true
      }
      document.body.removeChild(element)
      return false
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    使用方式

    // 如果复制成功返回true
    copyToBoard('lalallala')
    
    1
    2

    # 9. 休眠多少毫秒

    /**
     * 休眠xxxms
     * @param {Number} milliseconds
     */
    const sleep = (ms) => {
      return new Promise((resolve) => setTimeout(resolve, ms))
    }
    
    1
    2
    3
    4
    5
    6
    7

    使用方式

    const fetchData = async () => {
      await sleep(1000)
    }
    
    1
    2
    3

    # 10. 生成随机字符串

    使用场景:用于前端生成随机的 ID,毕竟现在的 Vue 和 React 都需要绑定 key

    /**
     * 生成随机id
     * @param {*} length
     * @param {*} chars
     */
    const uuid = (length = 8, chars) => {
      chars = chars || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
      let result = ''
      for (let i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]
      return result
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    使用方式

    // 第一个参数指定位数,第二个字符串指定字符,都是可选参数,如果都不传,默认生成8位
    uuid()
    
    1
    2

    # 11. 简单的深拷贝

    缺陷:只拷贝对象、数组以及对象数组,对于大部分场景已经足够

    /**
     *深拷贝
     * @param {*} obj
     * @returns
     */
    const deepCopy = (obj) => {
      if (typeof obj != 'object') return obj
      if (obj == null) return obj
      return JSON.parse(JSON.stringify(obj))
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    使用方式

    const person = { name: 'xiaoming', child: { name: 'Jack' } }
    deepCopy(person)
    
    1
    2

    # 12. 数组去重

    原理:利用 Set 中不能出现重复元素的特性

    /**
     * 数组去重
     * @param {*} arr
     */
    const uniqueArray = (arr) => {
      if (!Array.isArray(arr)) throw new Error('The first parameter must be an array')
      if (arr.length == 1) return arr
      return [...new Set(arr)]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    使用方式

    uniqueArray([1, 1, 1, 1, 1]) // [1]
    
    1

    # 13. 对象转化为 FormData 对象

    使用场景:上传文件时我们要新建一个 FormData 对象,然后有多少个参数就 append 多少次,使用该函数可以简化逻辑

    /**
     * 对象转化为formdata
     * @param {Object} object
     */
    
    const getFormData = (object) => {
      const formData = new FormData()
      Object.keys(object).forEach((key) => {
        const value = object[key]
        if (Array.isArray(value)) {
          value.forEach((subValue, i) => formData.append(key + `[${i}]`, subValue))
        } else {
          formData.append(key, object[key])
        }
      })
      return formData
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    使用方式

    const req = {
      file: 'xxx',
      userId: 1,
      phone: '15198763636',
    }
    getFormData(req)
    
    1
    2
    3
    4
    5
    6

    # 14. 保留到小数点以后 n 位

    使用场景:JS 的浮点数超长,有时候页面显示时需要保留 2 位小数

    const cutNumber = (number, no = 2) => {
      if (typeof number != 'number') number = Number(number)
      return Number(number.toFixed(no))
    }
    
    1
    2
    3
    4

    使用方式

    cutNumber(3.1415926)
    
    1

    # 15. 获取基础 URL

    const getBaseURL = (url) => url.replace(/[?#].*$/, '')
    
    1

    使用方式

    getBaseURL('http://url.com/page?name=Adam&surname=Smith') // 'http://url.com/page'
    
    1

    # 16. 判断网址是否为绝对网址

    const isAbsoluteURL = (str) => /^[a-z][a-z0-9+.-]*:/.test(str)
    
    1

    使用方式

    isAbsoluteURL('https://google.com') // true
    isAbsoluteURL('ftp://www.myserver.net') // true
    isAbsoluteURL('/foo/bar') // false
    
    1
    2
    3

    # 17. 获取 URL 参数作为对象

    const getURLParameters = (url) =>
      (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
        (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
        {},
      )
    
    1
    2
    3
    4
    5

    使用方式

    getURLParameters('google.com') // {}
    getURLParameters('http://url.com/page?name=Adam&surname=Smith') // {name: 'Adam', surname: 'Smith'}
    
    1
    2

    # 18. 检查元素是否包含另一个元素

    const elementContains = (parent, child) => parent !== child && parent.contains(child)
    
    1

    使用方式

    elementContains(document.querySelector('head'), document.querySelector('title')) // true
    elementContains(document.querySelector('body'), document.querySelector('body')) // false
    
    1
    2

    # 19. 获取元素的所有祖先

    const getAncestors = (el) => {
      let ancestors = []
      while (el) {
        ancestors.unshift(el)
        el = el.parentNode
      }
      return ancestors
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    使用方式

    getAncestors(document.querySelector('nav')) // [document, html, body, header, nav]
    
    1

    # 20. 平滑滚动元素进入视图

    const smoothScroll = (element) =>
      document.querySelector(element).scrollIntoView({
        behavior: 'smooth',
      })
    
    1
    2
    3
    4

    使用方式

    smoothScroll('#fooBar')
    smoothScroll('.fooBar')
    
    1
    2

    # 21. 处理元素外的点击

    const onClickOutside = (element, callback) => {
      document.addEventListener('click', (e) => {
        if (!element.contains(e.target)) callback()
      })
    }
    
    1
    2
    3
    4
    5

    使用方式

    onClickOutside('#my-element', () => console.log('Hello'))
    
    1

    # 22. 生成 UUID

    const UUIDGeneratorBrowser = () =>
      ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
        (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16),
      )
    
    1
    2
    3
    4

    使用方式

    UUIDGeneratorBrowser() // '0568875f-6106-4621-9bab-6be33b410027'
    
    1

    # 23. 获取选中的文本

    const getSelectedText = () => window.getSelection().toString()
    
    1

    使用方式

    getSelectedText()
    
    1

    # 24. 给 HTML 元素添加样式

    const addStyles = (el, styles) => Object.assign(el.style, styles)
    
    1

    使用方式

    addStyles(document.getElementById('my-element'), {
      background: 'red',
      color: '#ffff00',
      fontSize: '3rem',
    })
    
    1
    2
    3
    4
    5

    # 25. 切换全屏模式

    const fullscreen = (mode = true, el = 'body') =>
      mode ? document.querySelector(el).requestFullscreen() : document.exitFullscreen()
    
    1
    2

    使用方式

    fullscreen()
    fullscreen(false)
    
    1
    2

    # 26. 检测 Caps Lock 是否开启

    <form>
      <label for="username">Username:</label>
      <input id="username" name="username" />
      <label for="password">Password:</label>
      <input id="password" name="password" type="password" />
      <span id="password-message" style="display: none">大写锁定已开启</span>
    </form>
    <script>
      const el = document.getElementById('password')
      const msg = document.getElementById('password-message')
      el.addEventListener('keyup', (e) => {
        msg.style = e.getModifierState('CapsLock') ? 'display: block' : 'display: none'
      })
    </script>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 27. 看日期是否有效

    const isDateValid = (...val) => !Number.isNaN(new Date(...val).valueOf())
    
    1

    使用方式

    isDateValid('December 17, 1995 03:24:00') // true
    isDateValid('1995-12-17T03:24:00') // true
    isDateValid('1995-12-17 T03:24:00') // false
    isDateValid('Duck') // false
    isDateValid(1995, 11, 17) // true
    isDateValid(1995, 11, 17, 'Duck') // false
    isDateValid({}) // false
    
    1
    2
    3
    4
    5
    6
    7

    # 28. 从 Date 中获取冒号时间

    const getColonTimeFromDate = (date) => date.toTimeString().slice(0, 8)
    
    1

    使用方式

    getColonTimeFromDate(new Date()) // '09:39:08'
    
    1

    # 29. 从 Date 生成 UNIX 时间戳

    const getTimestamp = (date = new Date()) => Math.floor(date.getTime() / 1000)
    
    1

    使用方式

    getTimestamp() // 1720057242
    
    1

    # 30. 查看当前用户的首选语言

    const detectLanguage = (defaultLang = 'en-US') =>
      navigator.language ||
      (Array.isArray(navigator.languages) && navigator.languages[0]) ||
      defaultLang
    
    1
    2
    3
    4

    使用方式

    detectLanguage() // 'zh-CN'
    
    1

    # 31. 查看用户偏好的配色方案

    const prefersDarkColorScheme = () =>
      window && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
    
    1
    2

    使用方式

    prefersDarkColorScheme() // false
    
    1

    # 32. 查看设备是否支持触摸事件

    const supportsTouchEvents = () => window && 'ontouchstart' in window
    
    1

    使用方式

    supportsTouchEvents() // true
    
    1

    # 33. 通过 key 对数组对象进行分组

    目的:是将数组中的对象按指定的 key 进行分组。

    /* acc 参数是累加分组对象的累加器。obj 参数表示数组中的每个对象。
    在 reduce() 方法内部,使用扩展运算符 (...acc) 返回一个新对象。这将创建 accumulator 对象的浅表副本,以便可以在不更改原始对象的情况下对其进行修改。
    新对象的属性设置为与 key 参数的值相匹配的键。该属性的值是一个包含被迭代对象的数组。
    (acc[obj[key]] || []) 表达式检查该属性是否存在于累加器对象中。如果不存在,则返回一个空数组。展开运算符用于将数组与正在迭代的当前对象连接起来。
    最后,groupBy() 函数返回包含分组对象的累加器对象。
    */
    const groupBy = (arr, key) =>
      arr.reduce((acc, obj) => ({ ...acc, [obj[key]]: [...(acc[obj[key]] || []), obj] }), {})
    
    1
    2
    3
    4
    5
    6
    7
    8

    使用方式

    const people = [
      { name: 'Alice', age: 21 },
      { name: 'Bob', age: 22 },
      { name: 'Charlie', age: 21 },
      { name: 'David', age: 23 },
      { name: 'Eve', age: 22 },
    ]
    console.log(groupBy(people, 'age'))
    /* {
     21: [
      { name: "Alice", age: 21 },
      { name: "Charlie", age: 21 }
     ],
     22: [
      { name: "Bob", age: 22 },
      { name: "Eve", age: 22 }
     ],
     23: [{ name: "David", age: 23 }]
    }*/
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # 34. 返回数组的中位数

    // 当数组的元素个数为奇数时,排序数组的中值就是中间的元素。当数组元素个数为偶数时,中值取中间两个元素的平均值。
    const median = (arr) => {
      const sorted = arr.sort()
      const middle = Math.floor(sorted.length / 2)
      return sorted.length % 2 === 0 ? (sorted[middle - 1] + sorted[middle]) / 2 : sorted[middle]
    }
    
    1
    2
    3
    4
    5
    6

    使用方式

    const oddArr = [3, 1, 4, 2, 5]
    console.log(median(oddArr)) // 3
    const evenArr = [1, 2, 5, 6]
    console.log(median(evenArr)) // 3.5
    
    1
    2
    3
    4

    # 35. 返回数组中重复出现次数最多的值

    const mode = (arr) => {
      const counts = arr.reduce((acc, curr) => ({ ...acc, [curr]: (acc[curr] || 0) + 1 }), {})
      const maxCount = Math.max(...Object.values(counts))
      return Object.keys(counts)
        .filter((key) => counts[key] === maxCount)
        .map(Number)
    }
    
    1
    2
    3
    4
    5
    6
    7

    使用方式

    const arr1 = [1, 2, 3, 2, 4, 2, 5]
    console.log(mode(arr1)) // [2]
    const arr2 = [1, 2, 3, 2, 4, 4, 5]
    console.log(mode(arr2)) // [2, 4]
    
    1
    2
    3
    4

    # 36. 使用扩展运算符和 Array.from 创建一个长度为 n 的数组

    const createArr = (n) => [...Array.from({ length: n }, (_, index) => index)]
    
    1

    使用方式

    console.log(createArr(5)) // [ 0, 1, 2, 3, 4 ]
    
    1

    # 37. 使用解构获取数组的最后一个元素

    /*
    在 last() 函数内部,展开运算符 (...) 用于创建原始数组的副本。这是必需的,因为 pop() 方法会修改原始数组并返回删除的元素。
    然后,对数组的副本调用 pop() 方法,删除并返回数组的最后一个元素。由于在调用 pop() 方法之前复制了数组,因此不会修改原始数组。
    */
    const last = (arr) => [...arr].pop()
    
    1
    2
    3
    4
    5

    使用方式

    const people = [
      { name: 'Alice', age: 21 },
      { name: 'Bob', age: 22 },
      { name: 'Charlie', age: 21 },
      { name: 'David', age: 23 },
      { name: 'Eve', age: 22 },
    ]
    console.log(last(people)) // { name: "Eve", age: 22 }
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 38. 使用布尔构造函数检查变量是否为真

    const isTruthy = (val) => Boolean(val)
    
    1

    使用方式

    console.log(isTruthy(false)) // false
    console.log(isTruthy(0)) // false
    console.log(isTruthy(-0)) // false
    console.log(isTruthy(0n)) // false
    console.log(isTruthy('')) // false
    console.log(isTruthy(null)) // false
    console.log(isTruthy(undefined)) // false
    console.log(isTruthy(NaN)) // false
    console.log(isTruthy(true)) // true
    console.log(isTruthy({})) // true
    console.log(isTruthy([])) // true
    console.log(isTruthy(42)) // true
    console.log(isTruthy('0')) // true
    console.log(isTruthy('false')) // true
    console.log(isTruthy(new Date())) // true
    console.log(isTruthy(Infinity)) // true
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    # 39. 从数组中删除虚假值

    const compact = (arr) => arr.filter(Boolean)
    
    1

    使用方式

    const falsyArr = [false, 0, -0, 0n, '', null, undefined, NaN]
    const mixArr = [true, false, {}, 0, [], '', '0', null, 'false', undefined, 42]
    console.log(compact(falsyArr)) // []
    console.log(compact(mixArr)) // [ true, {}, [], '0', 'false', 42 ]
    
    1
    2
    3
    4

    # 40. 将字符串数组转换为数字

    const toNumbers = (arr) => arr.map(Number)
    
    1

    使用方式

    const strArr = ['1', '2', '3', '4', '5']
    console.log(toNumbers(strArr)) // [ 1, 2, 3, 4, 5 ]
    
    1
    2

    # 41. 返回一个键值翻转的对象

    /*
    Object.entries() 方法用于从原始对象创建键值对数组。然后使用 map() 方法迭代数组中的每个键值对,并返回一个新的翻转键值对数组。最后,使用 Object.fromEntries() 方法从翻转的键值对数组中创建一个新对象。
    */
    const flip = (obj) => Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))
    
    1
    2
    3
    4

    使用方式

    const myDog = {
      firstName: 'oscar',
      lastName: 'king',
      age: 3,
    }
    console.log(flip(myDog)) // { 3: 'age', oscar: 'firstName', king: 'lastName' }
    
    1
    2
    3
    4
    5
    6

    # 42. 返回一个指定 key 的对象

    /*
    在 pick() 函数内部,对 obj 参数调用 Object.entries() 方法以创建键值对数组。然后,在键值对数组上调用 filter() 方法。对于每个键值对,filter() 方法解构键变量,如果键数组包含键则返回 true。这将创建一个过滤后的键值对数组。
    最后,在过滤后的键值对数组上调用 Object.fromEntries() 方法来创建一个仅包含指定键及其对应值的新对象。pick() 函数返回新对象。
    */
    const pick = (obj, keys) => {
      if (!obj || !keys?.length) return {}
      return Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key)))
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    使用方式

    const myDog = {
      firstName: 'oscar',
      lastName: 'king',
      age: 3,
    }
    console.log(pick(myDog, [])) // {}
    console.log(pick(myDog, ['firstName'])) // { firstName: 'oscar' }
    console.log(pick(myDog, ['firstName', 'lastName'])) // { firstName: 'oscar', lastName: 'king' }
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 43. 返回一个对 value 去重的对象

    /*
    它首先在输入对象上调用 Object.entries() 方法以获取键值对数组。然后,它使用 filter() 方法过滤条目数组,并仅返回值唯一的条目。
    要检查一个值是否唯一,它在原始条目数组上使用 findIndex() 方法。它查找与当前过滤的条目具有相同值的第一个条目的索引。如果当前条目的索引等于第一个匹配条目的索引,则意味着该值是唯一的,应该包含在结果对象中。
    最后,它使用 Object.fromEntries() 方法将过滤后的条目数组转换回对象。
    */
    const uniqueValues = (obj) =>
      Object.fromEntries(
        Object.entries(obj).filter(
          ([key, value], index, entries) => entries.findIndex(([k, v]) => v === value) === index,
        ),
      )
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    使用方式

    const myDog = {
      id: 3,
      firstName: 'oscar',
      lastName: 'oscar',
      age: 3,
    }
    console.log(uniqueValues(myDog)) // { id: 3, firstName: 'oscar' }
    
    1
    2
    3
    4
    5
    6
    7
    #JavaScript
    上次更新: 2026/03/10, 15:18:38
    最近更新
    01
    龙虾(OpenClaw)搭建指南
    03-10
    02
    植物大战僵尸杂交版 v2.1 安装教程
    06-19
    03
    npm私有仓库搭建
    06-18
    更多文章>
    Theme by Vdoing | Copyright © 2021-2026 Ban Xian | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式