JS 实用技巧
前言
Javascript 可以做许多神奇的事情,也有很多东西需要学习,下面是收集日常开发中常用的代码片段。
位运算符(非 ~)
在数组的 findIndex
运算中,常常通过结果是否等于 −1 判断是否存在符合期望的子项,这也能通过非运算来简写:
const n = [1, 2, 3, 4]
const idx = n.findIndex((i) => i === 2)
// if (idx !== -1) {} // 通常的写法
// 相当于
if (~idx) {}
位运算符(或 |)
对一个数字| 0
可以取整,负数也同样适用,num | 0
1.5 | 0 // 1
-1.9 | 0 // -1
双位运算符~~
使用双位运算符来替代正数的 Math.floor()
与负数的 Math.ceil()
。双否定位操作符的优势在于它执行相同的操作运行速度更快。
Math.floor(4.9) === 4 // true
// 相当于
~~4.9 === 4 // true
Math.ceil(-4.5) === -4 // true
// 相当于
~~-4.5 === -4 // true
使用解构删除不必要属性
希望删除internal
和tooBig
参数。我们可以把它们赋值给internal
和tooBig
变量,然后在cleanObject
中存储剩下的属性以备后用。
const {_internal, tooBig, ...cleanObject} = { el1: '1', internal: 'secret', tooBig:{}, el2: '2', el3: '3' }
console.log(cleanObject)
保留指定的小数位
const toFixed = (n, fixed) => ~~(Math.pow(10, fixed) * n) / Math.pow(10, fixed)
// Examples
toFixed(99.198726354, 1) // 99.1
toFixed(99.198726354, 2) // 99.19
toFixed(99.198726354, 3) // 99.198
toFixed(99.198726354, 4) // 99.1987
toFixed(99.198726354, 5) // 99.19872
toFixed(99.198726354, 6) // 99.198726
反转字符串
const reverse = str => str.split('').reverse().join('')
// Examples
reverse('hello world') // 'dlrow olleh'
判断当前用户是否是苹果设备
使用 navigator.platform
const isAppleDevice = /Mac|iPod|iPhone|iPad/.test(navigator.platform)
console.log(isAppleDevice)
滚动至页面顶部
const goToTop = () => window.scrollTo(0, 0)
goToTop()
转换华氏/摄氏
const celsiusToFahrenheit = (celsius) => celsius * 9/5 + 32 // 摄氏温度转华氏温度
const fahrenheitToCelsius = (fahrenheit) => (fahrenheit - 32) * 5/9 // 华氏温度转摄氏温度
判断一个日期是否是工作日
const isWeekday = (date) => date.getDay() % 6 !== 0
console.log(isWeekday(new Date(2021, 0, 11))) // true (周一)
console.log(isWeekday(new Date(2021, 0, 10))) // false (周日)
获取所有参数的平均值
reduce()
方法计算
const average = (...args) => args.reduce((a, b) => a + b) / args.length
average(1, 2, 3, 4) // 2.5
关于拼接字符串
不要忘记了 ${}
里面可以写任意 JavaScript 表达式,运算和引用对象属性。
const name = 'huitoutunao'
const score = 59
return `${name}${score > 60 ? '合格' : '不合格'}`
关于添加对象属性
let obj = {}
let index = 1
obj[`topic${index}`] = '话题内容'
关于输入框非空的判断
if (value !== null && value !== undefined && value !== '') {
//...
}
优化
if ((value??'') !== '') {
//...
}
精确小数
const RoundNum = (num, decimal) => Math.round(num * 10 ** decimal) / 10 ** decimal
const num1 = RoundNum(9.59, 1)
const num2 = RoundNum(9.594, 1)
// num1 => 9.6
// num2 => 9.59
判断奇偶数
const OddEven = num => !!(num & 1) ? 'odd' : 'even'
const num = OddEven(2)
// num => "even"
补零
// 方案一
const FillZero1 = (num, len) => num.toString().padStart(len, '0')
const num1 = FillZero1(119, 4)
// num1 => 0119
// 方案二
const FillZero2 = (num, len) => (`0${num}`).slice(-len)
const num2 = FillZero2(9, 2)
// num2 => 09
转数值
只对 null、""、false、数值字符串
有效
const num1 = +null
const num2 = +''
const num3 = +false
const num4 = +'119'
// num1 num2 num3 num4 => 0 0 0 119
生成范围内的随机数
const RandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
const num = RandomNum(1, 10)
判断数据类型
可判断类型:undefined、null、string、number、boolean、array、object、symbol、date、regexp、function、asyncfunction、arguments、set、map、weakset、weakmap
function dataType(target, type) {
const data = Object.prototype.toString.call(target).replace(/\[object (\w+)\]/, "$1").toLowerCase()
return type ? data === type : data
}
dataType('str') // "string"
dataType(123) // "number"
dataType(true) // "boolean"
dataType([], "array") // true
是否为空数组
const arr = []
const flag = Array.isArray(arr) && !arr.length
// flag => true
是否为空对象
// dataType 上面实现的类型判断函数
const obj = {}
const flag = dataType(obj, "object") && !Object.keys(obj).length
// flag => true
过滤空值
空值:undefined、null、""、0、false、NaN
const arr = [undefined, null, "", 0, false, NaN, 1, 2].filter(Boolean)
// arr => [1, 2]
异步累计
async function Func(deps) {
return deps.reduce(async(t, v) => {
const dep = await t
const version = await Todo(v)
dep[v] = version
return dep
}, Promise.resolve({}))
}
const result = await Func() // 在 async 包围下使用
使用 .reduce() 替换 .map().filter()
const _arr = [0, 2, 4, 6]
// map.filter
const arr1 = _arr.map(v => v * 2).filter(v => v > 2)
// reduce
const arr2 = _arr.reduce((acc, cur) => {
cur = cur * 2
cur > 2 && acc.push(cur)
return acc
}, [])
reduce 按顺序执行 Promise
function runPromiseInSequence(arr, input) {
return arr.reduce(
(promiseChain, currentFunction) => promiseChain.then(currentFunction),
Promise.resolve(input)
)
}
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 5)
})
}
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2)
})
}
function f3(a) {
return a * 3
}
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4)
})
}
const promiseArr = [p1, p2, f3, p4]
runPromiseInSequence(promiseArr, 10).then(console.log) // 1200