一些JavaScript小技巧,是的代码更加简洁和高性能。
1. 过滤唯一值
ES6引入了Set对象和延层(spread)语法...,我们可以使用他们来创建一个只包含唯一值的数组。
const array = [1, 1, 2, 3, 3, 5, 8, 9, 5]
const uniqueArray = [...new Set(array)]
console.log(uniqueArray) // res: [1, 2, 3, 5, 8, 9]
在ES6之前,获得同样的数组需要更多的代码
这个技巧可以支持包含园视类型的数组: undefined, null, Boolean, string和number。但如果你的数组包含了对象,函数或其他嵌套数组,就不能用这种方法了。
2. 在循环中缓存数组长度
在开始学习for循环时,一般使用以下结构:
for (let i = 0; i< array.length; i++) {
console.log(i)
}
在使用这种方式时,for循环的每次迭代都会重复计算数组长度。
有时候这个会很有用,但在大多数情况下,如果能够缓存数组的长度会更好,这样只需要计算一次就够了。我们可以把数组的长度赋值给一个叫做length的变量,如:
for (let i = 0; length = array.length; i < length; i++) {
console.log(i)
}
两段代码差不多,但是从性能来看,即使数组变得很大,也不需要花费额外的运行时重复计算array.length
3. 短路求值
使用三元运算可以很快的写出条件语句,如:
x > 100 ? 'Above 100' : 'Below 100';
x > 100 ? (x > 200 ? 'Above 200' : 'Between 100-200') : 'Below 100'
但有时候三元运算符仍然很复杂,我们可以使用逻辑运算符 && 或 || 来替代,让代码更加简洁一些。这种技巧通常被称作“短路求值”。
假设我们想要返回两个或多个选项中的一个,使用&&可以返回第一个false,如果所有的操作数都是true,将返回最后一个表达式的值。
let one = 1, two = 2, three = 3;
console.log(one && two && three) // res: 3
console.log(0 && null) // res: 0
使用 || 可以返回第一个true, 如果所有的操作数的值都是false,将返回最后一个表达式的值。
let one = 1, two = 2, three = 3;
console.log(one || two || three) // res: 1
console.log(0 || null) // res: null
示例1
假设我们想要返回一个变量的length,但又不知道变量的类型。
我们可以使用if/false来检查foo是否是一个可接受的类型,但这样会让代码变得很长,这个时候就可以用短路求值:
return (foo || []).length;
对于上面两种情况,如果变量foo具有length属性,这个属性的值将被返回,否则返回0.
4. 转换成布尔值
除了标准的true和false,在JavaScript中,所有的值要么是“真值”要么是“假值”。
在JavaScript中,除了0、""、null、undefined、NaN和false是假值之外,其他的都是真值。
我们可以使用!云算法来切换true和false
const isTrue = !0;
const isFalse = !1;
const alsoFalse = !!0;
console.log(true); // res: true
consoel.log(typeof true) // res: "boolean"
5. 转换成字符串
要快速将数字转换成字符串,可以使用+运算符,然后在后面加上一个空字符串
const val = 1 + '';
console.log(val) // res: "1"
console.log(typeof val) // res: "string"
6. 转换成数字
要把字符串转成数字,也可以使用+运算符
let int = '15';
int = +int;
console.log(int); // res: 15
console.log(typeof int) // res: 'number'
也可以使用这种方式将布尔值转换成数字
console.log(+true); // res: 1
console.log(+false); // res: 0
在某些情况下,+运算符会被解析成连接操作而不是加法操作。对于这种情况,可以使用两个波浪号:~~
一个波浪号表示按位取反,如: ~15等于-16.
const int = ~~'15'
console.log(int); // res: 15
console.log(typeof int); // res: 'number'
使用两个波浪号可以再次取反,因为-(-n-1) = n+1-1,所以~-16等于15
7. 快速幂运算
从ES7开始,可以使用**进行幂运算,比使用Math.power(2, 3)要快得多
// 以下的表达式是等效的
Math.power(2, n);
2<<(n-1);
2**n;
例如: 2<<3 = 16 等同于 2**4 = 16
8. 快速取整
将浮点数转成整数,可以使用Math.floor()、Math.ceil()或Math.round(),还有一种更快的方法,就是使用位或运算符|。
console.log(22.2 | 0); // 22
console.log(-16.87 | 0); // -16
| 的实际操作行为取决于操作数是正数还是负数,所以在使用这个运算符时要确保你知道操作数是正还是负。
如果n是正数,那么n|0向下取整,否则就是向上取整,它会移除小数部分,也可以使用~~达到相同的效果。
移除整数尾部数字
|运算符也可以用来移除整数的尾部数字,这样就不需要像下面这样写
let str = '1586'
Number(str.substring(0, str.length - 1))
可以这样
console.log(1455/10 | 0) // 145
console.log(1455/100 | 0) // 14
console.log(1455/1000 | 0) // 1
9. 自动类绑定
在ES6中,可以使用箭头函数进行隐式绑定,这样可以位类的构造器省下一些代码,并且避免一些重复出现的表达式,比如 this.myMethod = this.myMethod.bind(this)
import React, { Component } from React;
export default class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
myMethod = () => {
// this method is bound implicitly!
}
render() {
return {
<>
<div>
{this.myMethod()}
</div>
</>
}
}
}
10. 截取数组
如果想从数组的尾部移除某些元素,可以使用一些比splice() 更快的方法。
例如,如果知道初始数组的大小,可以像下面这样重新定义它的length属性
let array = [1, 1, 2, 3, 4, 5, 5, 6, 7, 8]
array.length = 4
不过slice() 的速度更快,如果更看重速度,可以这样写
let array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array = array.slice(0, 4)
11. 获取数组最后的元素
数组的slice() 方法可以接收负参数,并从数组的尾部开始获取元素。
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(array.slice(-1)) // [9]
console.log(array.slice(-2)) // [8, 9]
console.log(array.slice(-3))// [7, 8, 9]
12. 格式化JSON
JSON.stringify还可以用来给JSON添加缩进
stringify()方法可以接收两个额外的参数,一个是函数(形参为replacer),用于过滤要显示的JSON,另一个是空格个数(形参为space)。space可以是一个整数,表示空格的个数,也可以是一个字符串(比如'\t'表示制表符),这样得到的JSON更加容易阅读。
console.log(JSON.stringify({ alpha: 'A', beta: 'B' }, null, '\t'));
// Result:
// '{
// "alpha": A,
// "beta": B
// }'