Yakim shu Hi, 這是我擴充腦內海馬體的地方。

[第二週] 基礎 JavaScript - 01 邏輯、位元運算

介紹 Node.js

Node.js 是一個 JavaScript 的執行環境。

在 Node.js 出現之前,JavaScript 只能在瀏覽器上運行,Node.js 就是提供 Javascript 除了瀏覽器以外的運行環境。


題外話小技巧


基本邏輯的短路性質

以前對於 ||&& 邏輯運算子的看法是,不就是以前國中學過的嗎?這麼簡單有什麼好講的,但當時看 JavaScript 犀牛書的時候不禁讚嘆:「 原來還可以這樣?! 」,不過這節還是補充了以前不知道的資訊,太好了!

注意

在 JavaScript 裡,代表 false 的就只有幾個: 0-0NaNnullundefined"" ( ← 空字串 ),所以搞清楚 false 還蠻重要的喔,不然往後的日子應該有很多坑可以跳。

剛好複習一下當時的筆記:


|| 邏輯運算子 OR

undefined || 0 || "hello" || false  // 找到 true 回傳
> "hello"
NaN || 0 || undefined || "" || null // 全部都為 false,回傳最後一個 false 的值
> null

&& 邏輯運算子 AND

"hello" && 10 && "" && 1 // 找到 false 回傳
> ""
10 && "world" && 1 // 全部都為 true,回傳最後一個 true 的值
> 1

位元運算

位元運算真的很有趣,今天整個下午都花在這了,吳鎮宇說的沒錯:「 出來混,遲早要還的 」一度逃避的東西還是被默默回來找你。

大四的時候很想學網頁,學姊跟我說:「可以去看 JavaScript。」,然後就去了學校圖書館找 JavaScript 的書,其他的運算子都非常好懂,直到翻開位元運算的那一頁,就沒有再翻過下一頁了。( 而且後來才發現我借到 Java… )

( 回到正題,跳一下 )

要了解什麼是位元運算,首先要介紹位元位移,要知道什麼是位元位移,首先要有 2 進位的觀念。

( 不難、先不要崩潰 )

2^i 2⁵ 2⁴ 2⁰ 數字
32 16 8 4 2 1  
範例 A 0 1 1 0 1 0 16+8+2 = 26
範例 B 1 0 0 1 0 1 32+4+1 = 37

意思是說 26 的二進制表示法為 01101037 的二進制表示法為 100101


>><< 位元位移

>> 位元右移

<< 位元左移

// 往左位移( 後面補 0 )
A: 011010 << 1 → 0110100 // 等於 26 << 1 等於 26 * 2 == 52
A: 011010 << 2 → 01101000 // 等於 26 << 2 等於 26 * 4 == 104

// 往右位移( 後面直接捨去 )
A: 011010 >> 1 → 001101 // 等於 26 >> 1 等於 26 / 2 == 13
A: 011010 >> 2 → 000110 // 等於 26 >> 2 等於 26 / 4 == 6 ( 餘數無條件捨去 )

那這樣很不直覺的運算到底能幹嘛呢?

答案是在效能上有所差異,因為電腦只認得二進制的機器碼,所以照理來說,同樣得出 n * 2 的運算結果,n << 1 會比 n * 2 還要來得快。


|&^ 位元運算子

注意:

不要把位元運算子 |& 跟邏輯運算子 ||&& 搞混了,可以把位元運算子理解成 2 進位版的邏輯比較


| 位元 OR

當成位元間的 ||,以 0011 | 1001 ( 3 | 9 ) 為例,會回傳 1011 ( 11 )

| 運算結果 1 0 1 1 11
範例 A 0 0 1 1 3
範例 B 1 0 0 1 9

可以拆解成以下步驟:

- 2^3 → 0 || 1 → 1 
- 2^2 → 0 || 0 → 0 
- 2^1 → 1 || 0 → 1 
- 2^0 → 1 || 1 → 1

& 位元 AND

當成位元間的 &&,以 0011 & 1001 ( 3 & 9 ) 為例,會回傳 0001( 1 )

& 運算結果 0 0 0 1 1
範例 A 0 0 1 1 3
範例 B 1 0 0 1 9

可以拆解成以下步驟:

- 2^3 → 0 && 1 → 0 
- 2^2 → 0 && 0 → 0 
- 2^1 → 1 && 0 → 0 
- 2^0 → 1 && 1 → 1

^ 位元 XOR

最特別的一種,只有當兩邊是一樣的0 ^ 01 ^ 1 的時候才會回傳 0

同樣以 0011 ^ 1001 ( 3 ^ 9 ) 為例,會回傳 1010( 10 )

^ 運算結果 1 0 1 0 10
範例 A 0 0 1 1 3
範例 B 1 0 0 1 9

可以拆解成以下步驟:

- 2^3 → 0 ^ 1 → 1 
- 2^2 → 0 ^ 0 → 0 
- 2^1 → 1 ^ 0 → 1 
- 2^0 → 1 ^ 1 → 0

注意: 上面的 2^3,是為了方便表示 2 的 3 平方,不要跟 ^ 位元運算子搞混了。


應用

又回到每天都要問的問題,所以到底能幹嘛勒?!

做個小實驗,把任意數字 n1& 位元運算會發生什麼事?

猜出來了嗎?將 n & 1判斷 n 是奇數 or 偶數的小技巧。除了使用 n % 2 “ 取餘數 “ 的傳統方式,n & 1 是個效能更好的方法。

10 & 1 → 0 // 偶數
11 & 1 → 1 // 奇數

再把任意數字 n2的任意平方& 位元運算會發生什麼事?


結論

本章學到兩個效能更好的實用小技巧,稍微複習一下:


( 以上內容大部分是 程式導師實驗計畫第三期 的學習筆記,如有錯誤歡迎糾正,非常感謝 🤓 )