Javascript代码中的骚操作

笔者是一个喜欢将JavaScript各种骚操作进行到底的一个人,且不喜欢添加注释的那一种。曾经有小伙伴接手过我的一个项目,看完代码后,差点要揍我,第二天沉默的向领导提出了辞职。

下面给大家总结一些JavaScript代码中的一些容易让人琢磨不透的,让人一看就很装X的,并且很实用的,提升代码运行效率的写法。

 

位运算

前端小伙伴们都知道,在实际运算中,js是很容易丢失精度的,这就造成了Javascript中最臭名昭著的0.1 + 0.2  !== 0.3的BUG众多大牛们不推荐使用位运算符进行公式计算,在笔者看来,如果你的js技能足够强大,能避开各种坑的话,偶尔用一下位运算还是very good的。Javascript全套套用了Java的位运算,在Js中套用位运算能够提升运算性能。

1.奇偶数判断

// 普通写法,多采用取模(%)的方法
2 % 2 = 0 // 偶数
3 % 2 = 1 // 奇数
num % 2 === 0 ? '偶数' : '奇数'

/*
* & 运算符的写法
* &以特定的方式组合操作二进制数中对应的位
* 如果对应的位都为1,那么结果就是1
* 如果任意一个位是0 则结果就是0
* 
* */
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// 3的二进制表示为: 00000000 00000000 00000000 00000011
2 & 1 = 0
3 & 1 = 1
num & 1 === 0 ? '偶数' : '奇数'

2.切换0和1(可以互相取反)

// 常用于toogle的状态取反,比如vue中的弹框显示
data: {
  status: false,
  value: ''
}

// 第一次运算
this.status ^= 1  // 打印出来为1
// 再一次运算
this.status ^= 1  // 打印出来为0

//或者判断某个属性值是否存在
if(this.value) {return 1} return 0; // 普通写法
this.value ? 1 : 0 // 三目运算法
this.value ^= 1 // 打印出来为1,位运算法
this.value ^= 1 // 打印出来为0,位运算法

3.转换布尔值(用于确定状态的赋值)

此处一个新的位运算法“!!”,非0的的都是true,包括浮点数和负数

// 普通写法
const status = Boolean(0) // false
const status = Boolean(1) // true
// !!写法
const status = !!0; // false
const status = !!1; // true
const status = !!7; // true
const status = !!-7; // true
const status = !!-7.121212; // true

4.已知值+1( ~的用法)

~运算符是对位求反,1变0,0变1,也就是求二进制的反码

// 普通用法
let a = 1; a = a + 1
或者
let a = 1; a++

/*
* ~的用法
* 简单记忆:自身值 + 1后取负数
* ~运算后位负值,故Math.abs区绝对值
* */
let a = 1; Math.abs(~a)

5.左移(<<)和右移(>>)

需要了解二进制的内部运算机制,相对较复杂哦,有兴趣的小伙伴们可以网上了解一下。常用场景主要是幂数求值等。需要了解二进制的内部运算机制,相对较复杂哦,有兴趣的小伙伴们可以网上了解一下。常用场景主要是幂数求值等。

6.使用~、<< 、>>、>>>、|取整

// 相当于使用了Math.floor()的方法
Math.floor(11.223344)  // 11
console.log(~~11.223344)     // 11
console.log(11.223344 >> 0)  // 11
console.log(11.223344 << 0)  // 11
console.log(11.223344 | 0)   // 11
console.log(11.223344 >>> 0) // 11


&&,||, !的使用

1.if判断语句的优雅写法

// 普通用法
let str = ''
if (a === 'clear') {
  str = '清空'
} else if(a === 'delete') {
  str = '删除'
} else if (a === 'add') {
  str = '添加'
} else {
  str = '未知'
}
// switch用法
switch(a) {
  case 'clear': str='清空';break;
  case 'delete': str='删除';break;
  case 'add': str='添加';break;
  default: str='未知';
}

// Object写法
str = {
  clear: '清空',
  delete: '删除',
  add: '添加'
}[a] || '未知'


// 使用 && 和 || 的语法
str = (a === 'clear' && '清空') || (a === 'delete' && '删除') || (a === 'add' && '添加') || '未知';

2.相同条件的不同赋值

// 当相同条件的赋值是或关系时,我见过太多的小伙伴是这样写的
if (a === '1' || a === '2') {
  // TODO
} 

// 及其的low啊,难道数组的includes方法你不知道?
if(['1', '2'].includes(a)){
 // TODO
}
// 单一判断逻辑下,直接 && 表示执行
['1', '2'].includes(a) && // TODO

广州vi设计公司 http://www.maiqicn.com 我的007办公资源网 https://www.wode007.com

数组的不常见写法(多用展开符...)

1.数组去重

// 循环遍历式的去重就不重复了
// TODO

// ES6 set方法
Array.from(new Set([1,2,3,4,3,2,1])); //[1, 2, 3, 4]
[...new Set([1,2,3,4,3,2,1])]; //[1, 2, 3, 4]

2.数组合并

// 普通写法
[1,2,3,4].concat([5,6]);//[1, 2, 3, 4, 5, 6]
// 使用展开符
[...[1,2,3,4],...[5,6]];//[1, 2, 3, 4, 5, 6]

3.判断数组的条件满足性

// 每一项是否满足
[1,2,3,4].every(item => {return item > 2});//false
// 有一项满足
[1,2,3,4].some(item => {return item > 2});//true

4.数组常用方法在此

// 其他常用的数组操作方法:

sort() //升序
reverse() //倒序,反转
join() //将数组转为字符串
push() //添加到数组末尾
pop() //末尾移除最后一项
unshift() //添加到原数组开头
shift() //删除数组第一项
slice() //返回起始位置到结束位置之间的项[m,n) 不改变原数组
splice() //传两个参(m,n) 删除从m到n个之间的项 改变原数组; 传三个参(m,n,k)从当前m到n个前插入k
concat() //将参数添加到原数组中,不改变原数组
of() //将不是数组的转化为数组
fill() //用一个固定值填充一个数组中从起始索引到终止索引内的全部元素
posted @ 2020-09-16 15:34  笑人  阅读(468)  评论(0编辑  收藏  举报