JavaScript中简单而有效的用法

追踪者
• 阅读 741

数组去重

使用ES6中提供的Set数据结构

const arr = [1, 2, 3, 4, 3, 2, 1]
const newArr = [...new Set(arr)]
// 或
const newArr = Array.from(new Set(arr))

console.log(newArr)

使用数组中的reduce方法

const arr = [1, 2, 3, 4, 3, 2, 1]

const newArr = arr.reduce((result, item) => {
  if (!result.includes(item)) {
    result.push(item)
  }
  return result
}, [])

console.log(newArr)

变量交换

假设现在有a,b两个变量,在不依赖于临时变量的情况下,如何快速的实现变量之间的值交换呢?

解构赋值

let a = 1
let b = 2
[a, b] = [b, a]

console.log(a, b) // a --> 2, b --> 1

位异或

let a = 1
let b = 2

// 使用位异或运算
a = a ^ b
b = b ^ a
a = a ^ b

// 或直接交换
a = a + b
b = a - b
a = a - b

console.log(a, b) // a --> 2, b --> 1

借用数组

let a = 1
let b = 2

b = [a, a = b][0]

console.log(a, b) // a --> 2, b --> 1

字符串分组

将字符转以特定的字符进行分组, 比如按照空格,逗号,分号字符进行分组

const str = 'a b,c;d,e f,cf'

const result = str.match(/[^\s,;]+/g)

// result -> ["a", "b", "c", "d", "e", "f", "cf"]

随机字符串

利用Math.random()生成随机数字,然后再通过tostring方法将其转换为随机字符串

const str = Math.random().toString(36).substr(2)

console.log(str) // --> "3mknchm44dt"

密码强度判断

判断规则:

  • 长度必须大于6
  • 包含数字,密码强度+1
  • 包含大/小写字母,密码强度+1
  • 包含除数字和大小写字母外的其他字符,密码强度+1
function getStrength(str) {
  let strength = 0
  if (str && str.length >= 6) {
    if (/\d+/.test(str)) {
      ++strength
    }
    if (/[a-zA-Z]+/.test(str)) {
      ++strength
    }
    if (/[^0-9a-zA-Z]+/.test(str)) {
      ++strength
    }
  }

  return strength
}

首字母大写

使用CSS

.text {
  text-transform: capitalize;
}

使用JS

const upperCase = data => {
  if (data) {
    const [first, ...char] = data

    return first.toUpperCase() + char.join('')
  }

  return ''
}

console.log(upperCase('hello'))

这里用到了字符串的解构赋值,即将第一个字母赋值给first,其余字母赋值到char中,从而实现将首字母转换为大写。

链判断运算符

在开发中,如果需要读取对象内部的某个属性,往往需要判断该对象是否存在。比如,需要获取result.userInfo.username中的username,为了避免js报错,一般的写法为:

const { username } = result.userInfo || {}
// 或
const username = result.userInfo ? result.userInfo.username : ''

这样,每一层对象的属性都必须判断是否存在,对象层级关系较大,则写法更加复杂。好在ES2020 为我们提供了链判断运算符(?.),上述的代码可以简化为

const username = result?.userInfo?.username
// 等同于
const username = result && result.userInfo ? result.userInfo.username : undefined

const name = form.querySelector('input')?.value
// 等同于
const name = form.querySelector('input') ? form.querySelector('input').value : undefined

链判断运算符也可以判断方法是否存在

actions?.getuserInfo?.()
// 等同于
actions && actions.getUserInfo ? actions.getUserInfo() : undefined

但是,在现代浏览器中,还不支持这种写法,所以我们必须借助babel将它转义为现代浏览器可识别的代码。

  • 安装依赖 yarn add -D @babel/plugin-proposal-optional-chaining
  • 在.babelrc中进行配置
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    "@babel/plugin-proposal-optional-chaining"
  ]
}

接下来就可以愉快的使用链判断运算符啦!

复制内容到剪切板

复制任何内容到剪切板,并返回一个promise

function setStyle (el, styleName, value) {
  if (el && styleName) {
    if (typeof styleName == 'object') {
      for (let key in styleName) {
        setStyle(el, key, styleName[key])
      }
    } else {
      el.style[styleName] = value
    }
  }
}

function copyText(value) {
  return new Promise((resolve, reject) => {
    const el = document.createElement('input')

    el.setAttribute('readonly', 'readonly')
    setStyle(el, {
      fontSize: '12px',
      border: 0,
      outline: 0,
      margin: 0,
      padding: 0,
      position: 'fixed',
      top: 0,
      left: '-9999px',
      zIndex: -10
    })
    el.value = value
    document.body.appendChild(el)
    el.select()
    el.setSelectionRange(0, String(value).length)

    if (document.execCommand('Copy')) {
      resolve(value)
    } else {
      reject(new Error('Copy failed'))
    }

    setTimeout(() => {
      el.remove()
    }, 3000)
  })
}

copyText('hello world')
  .then(() => console.log('success'))
  .catch(e =>  console.log(e.message))

防抖和节流

防抖

概念:防抖的作用在于,如果某个事件或函数在某个时间段内连续触发,那么只有最后一次触发,事件回调或函数才会被真正的调用。如浏览器的resize, scroll, mousemove等事件。在短时间内会被多次触发,如果不加以限制,不仅浪费客户端资源,还有可能造成客户端卡顿,卡死以及崩溃。如果有网络请求,短时间内大量的网络请求还会造成网络堵塞(由于浏览器的限制,一般浏览器只能同时处理6个左右的请求,当请求过多时,只有等请求队列中的请求都完成后,才会开始下一个请求,否则排队中的请求一直处于等待状态,无法被处理)以及增加服务器压力。

function debounce(fn, timeout = 500) {
  // 这里通过闭包使timer变量不会被JS垃圾回收机制回收,从而常驻内存中
  let timer = null

  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, args)
        timer = null
      }, timeout)
    }
  }
}

// 这里将函数通过节流函数封装后返回`fn`
const fn = debounce(() => console.log('debounce'))

节流

概念:顾名思义,节流的意义在于限制其流入/流出量。通常用在当一个事件或函数在某个时间内连续触发或调用时,在一定时间段内,只调用一次事件处理函数。如某个事件在特定的情况下,20秒内触发了50次,每次都会向服务器发送数据请求,通过节流限制其执行次数,即1s内只允许其执行1次,这样大大的减少了请求数量,减轻服务器压力的同时,也减少了客户端的内存开销,避免了出现内存泄漏。

function throttle(fn, delay = 1000) {
  let last = 0

  return function(...args) {
    const current = Date.now()
    if (current - last > delay) {
      fn.apply(this, args)
      last = current
    }
  }
}

一言以蔽之,防抖函数的作用在于在特定时间内连续触发的事件,只有最后一次会被执行。节流函数的作用在于,在固定时间内连续被触发的事件在n秒内只能被触发执行一次。


及时获取更新,了解更多动态,请关注 https://www.gogoing.site

如果你觉得这篇文章对你有帮助,欢迎关注微信公众号-前端学堂,更多精彩文章等着你!

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这