不二如是 发表于 2020-1-25 21:09:53

0 2 4 3 ★ 牛X到很骚的 JS 移位操作|【只有魔法才能对抗魔法】

本帖最后由 不二如是 于 2020-2-4 20:59 编辑

上一篇:0 2 4 2★ TypeScript 一统天下,JavaScript 败北??

static/image/hrline/2.gif



JavaScript 中最臭名昭著的 Bug 就是:

0.1 + 0.2 !== 0.3
因为精度的问题,导致所有的浮点运算都是不安全的。

有一种观点不要在 JS 中使用位运算:

Javascript 完全套用了 Java 的位运算符,包括按位与 &、按位或 |、按位异或 ^、按位非 ~、左移 <<、带符号的右移 >> 和用 0 补足的右移>>>。

这套运算符针对的是整数,所以对 JavaScript 完全无用,因为 JavaScript 内部,所有数字都保存为双精度浮点数。

如果使用它们的话,JavaScript 不得不将运算数先转为整数,然后再进行运算,这样就降低了速度。
而且"按位与运算符"&同"逻辑与运算符"&&,很容易混淆。

个人觉得:

如果对 JS 的运用达到炉火纯青的地步,能避开各种小“坑”的话,偶尔用一下位运算符也无所谓,还能提升运算性能,毕竟直接操作的是计算机最熟悉的二进制。

接下来就是几个很骚的操作。


使用左移运算符 << 迅速得出 2 的次方

1 << 2



2 的 2 次方。

同理:

1 << 10 // 1024, 即 2的10次方// 但是要注意使用场景
a = 2e9;   // 2000000000a << 1;    // -294967296

使用 ^ 切换变量 0 或 1

接下来 3 段语句都是一样滴:

// --- before ---// if 判断
if (toggle) {    toggle = 0;}
else {    toggle = 1;}

// 三目运算符
togle = toggle ? 0 : 1;

// --- after ---
toggle ^= 1;

使用 & 判断奇偶性

偶数 & 1 = 0

奇数 & 1 = 1

代码:

console.log(7 & 1);    // 1
console.log(8 & 1) ;   // 0

使用 !! 将数字转为布尔值

所有非 0 的值都是 true,包括负数、浮点数:

console.log(!!7);       // true
console.log(!!0);       // false
console.log(!!-1);      // true
console.log(!!0.71);    // true

使用 ~、>>、<<、>>>、| 来取整

相当于使用了 Math.floor()

console.log(~~11.71)   // 11
console.log(11.71 >> 0)// 11
console.log(11.71 << 0)// 11
console.log(11.71 | 0)   // 11
console.log(11.71 >>> 0) // 11
注意:注意 >>> 不可对负数取整

若强行:
-33.333 >>> 0 //4294967263

使用 ^ 来完成值交换

介绍一些高级的用法,在 ES6 的解构赋值出来之前,用这种方式会更快(但必须是整数):

// --- before ---
let temp = a; a = b; b = temp; // 传统,但需要借助临时变量
b = // 借助数组

// --- after ---
let a = 7
let b = 1
a ^= bb ^= aa ^= b
console.log(a)   // 1
console.log(b)   // 7
= ; // ES6,解构赋值

使用 ^ 判断符号是否相同

这个有点多此一举,还是列出来吧:
(a ^ b) >= 0; //true 相同; false 不相同
说完移位操作,再来介绍一些其他相似的吧。


使用 toString(16) 取随机字符串

Math.random().toString(16).substring(2, 15);



.substring() 的第二个参数控制取多少位 (最多可取 13 位)。


使用当前时间创建一个随机数

// --- before ---
let b = 0 | Math.random() * 100

// --- after ---
let a;a = new Date % 100; // 两位随机数
a = new Date % 1000; // 三位随机数
a = new Date % 10000; // 四位随机数
不要在快速循环中使用,因为毫秒可能没有变化。


for 循环条件的简写

// --- before ---
for(let i = 0; i < arr.length; i++) {...}

// --- after ---
for(let i = arr.length; i--;) {...}
注意 i-- 后面的分号别漏了!

最后,来一个彩蛋,如果以后有人喷你的代码,你就可以将此代码发给他。

在控制台输入:

(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]]
猜猜结果是什么呢{:10_307:}

static/image/hrline/2.gif

下一篇:0 2 4 4 ★ JavaScript 死了吗??



如果喜欢,别忘了评分{:10_281:} :

http://xxx.fishc.com/forum/201709/19/094516hku92k2g4kefz8ms.gif

这位鱼油,如果喜欢本系列Js帖子,请订阅 专辑☞(传送门)(不喜欢更要订阅{:10_297:} )

zltzlt 发表于 2020-1-25 21:14:01

哇塞,好骚好喜欢{:10_278:}

zltzlt 发表于 2020-1-26 21:29:51

JavaScript 中最臭名昭著的 Bug 就是:

0.1 + 0.2 !== 0.3

不仅是 JS,所有语言都是这样。

例如 Python:

TCY 发表于 2020-2-5 12:22:33

zltzlt 发表于 2020-1-26 21:29
不仅是 JS,所有语言都是这样。

例如 Python:

20000000000%的同意

weiter 发表于 2020-3-2 16:07:08

哇塞,好骚好喜欢{:10_278:}

LuckyTiger66 发表于 2020-3-17 06:45:31

本帖最后由 LuckyTiger66 于 2020-3-17 07:20 编辑

哇塞,好骚好喜欢{:10_278:}

if (toggle) {    toggle = 0;}
else {    toggle = 1;}
//toggle == 1或 true 時,反而是0,比較不直觀。

{:5_94:} 這一串SB??
(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]]
页: [1]
查看完整版本: 0 2 4 3 ★ 牛X到很骚的 JS 移位操作|【只有魔法才能对抗魔法】