Node.js 環境建置、邏輯運算、位元運算


Posted by saffran on 2020-12-01

該如何執行 JavaScript?

一直以來,JavaScript 都只能在瀏覽器上面執行

直到出現了 Node.js

Node.js 是一個執行環境(不是一個程式語言),能夠讓 JavaScript 在瀏覽器外面執行,也就是可以跑在我的電腦上

在瀏覽器裡寫 JavaScript

方法一:用 vim 寫 JS 程式碼

  1. 在 CLI 用 vim 建立(開啟)一個檔案叫做 index.html
    vim index.html
    
  2. 在 vim 裡面輸入 <script></script> 的標籤之後,就可以開始在 <script></script> 標籤裡面寫 JS 程式碼了
    (因為這個是 html 檔案,所以要用 <script></script> 標籤把 JS 程式碼包起來)
    <script>
    console.log('Monday')
    </script>
    
  3. 在瀏覽器開啟 index.html,打開 devtool,就可以看到剛剛寫的程式碼了
    ## 方法二:直接在瀏覽器的 Console 寫 JS 程式碼

用 Node.js 執行 JS

方法一:

  1. 在 CLI 用 vim 建立(開啟)一個檔案叫做 index.js
    vim index.js
    
  2. 就可以直接開始寫 JS 程式碼了
    console.log('Monday')
    
  3. 回到 CLI 輸入 node index.js,就可以看到剛剛我想要印出的東西了
    node 檔案名稱
    

方法二:

要用 Node.js 執行 JS,還有另一種方式是:

在 CLI 輸入 node 按下 Enter 後,就可以開始寫 JS 了

例如:

輸入 console.log(789) 後就會印出 789

下面那行 undefined 可以不用理它,它只是 console.log(789) 這個函式的回傳值

要離開 Node.js,就按下 ctrl + C

邏輯運算:|| 與 && 的短路性質

什麼是短路性質呢?

舉例來說

|| or

範例一:
當我在 Node.js 輸入 5 || 30
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,當它跑到 5 時,就是 true 了,所以就不會再去看後面的值,就會直接回傳 5

5 || 30

範例二:
當我在 Node.js 輸入 false || 20
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,它要跑到 20 時,才會知道整個句子的結果是 true ,所以就會回傳 20

false || 20

範例三:
當我在 Node.js 輸入 0 || console.log(789)
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,它看完 0 之後(0 是 false),要再跑到 console.log(789) 時,才會知道整個句子的結果是 true ,所以就會回傳 789

0 || console.log(789)

&& and

範例一:
當我在 Node.js 輸入 false && 50
因為「and」就是「一定要兩個都是 true,整個句子才會是 true」

因此,當它跑到 false 時,就是 false 了,所以就不會再去看後面的值,就會直接回傳 false

false && 50

範例二:
同樣地,輸入 0 && 8999 會回傳 0,因為 0 就已經是 false 了

0 && 8999

範例三:
當我在 Node.js 輸入 8 && 27
因為「and」就是「一定要兩個都是 true,整個句子才會是 true」

因此,它必須把兩個值都看完

  • 8 是 true
  • 但是,還是要跑到 27,才確定整個句子的結果是 true,因此會回傳 27
8 && 27

看它最後跑到哪個值,就回傳哪個值--> 這個就叫做「短路性質」(因為有時候根本不需要看後面的值,就可以決定整個句子的值是 true 還是 false)

true 真的值

true 就是「真的」值

false 假的值

直覺覺得它是「沒有」的東西,就是 false(假的值)

例如:0、空字串、null

位移運算子

位移運算,是位元運算的其中一塊:是針對「位元(每一個 bit)」來做操作,而不是針對整體

對「2 進位」來說
0100 = 2^2 = 4
1000 = 2^3 = 8

0100 往左移 1 位,就是 1000,也就是「乘以 2」

因此,對「2 進位」來說

  • 把每一個位元都往左移 1 位,就是「* 2」
  • 把每一個位元都往右移 1 位,就是「/ 2」

運用「位元運算」的性質,來達到「* 2」、「/ 2」

例如:

往左移 <<

  • 把 10 往左移 1 位,會回傳 20
    10 * 2^1
    10 << 1
    
  • 把 10 往左移 3 位,會回傳 80
    10 * 2^3
    10 << 3
    
  • 把 1 往左移 10 位,會回傳 1024
    1 * 2^10
    1 << 10
    

往右移 >>

往右移如果不能整除的話,就會無條件捨去

  • 把 1024 往右移 1 位,會回傳 512
    10 / 2^1
    1024 >> 1
    
  • 把 9 往右移 1 位,會回傳 4
    9 / 2^1 = 4.5 無條件捨去 = 4
    9 >> 1
    
    ## 位移運算子的優點
    使用「左移、右移」運算子的方式來乘以 2、除以 2,比起直接使用「* 2」、「/ 2」,效能更快

原因是:二進位對電腦來說,是最原始的形式,因此效能通常都會最好

位元運算的 and、or、xor 與 not

先把數字變成二進位,再針對二進位的每一個位數去做運算

只有一個 & 時,就會做「位元運算」

& 位元運算的 and

例如:
之前在講邏輯運算子時,輸入 10 && 15 會回傳 15,因為這裡做的是「邏輯運算」

但是
如果是輸入 10 & 15 會回傳 10,因為這裡做的是「位元運算」

10 & 15

運算的模式如下

會先把 10 和 15 變成二進位:

  • 10 會是 1010
  • 15 會是 1111

然後再針對每一個位元去做 & 的運算,因為這裡是使用 & (and)

  • 第 1 個位數:0 & 1 會是 0
  • 第 2 個位數:1 & 1 會是 1
  • 第 3 個位數:0 & 1 會是 0
  • 第 4 個位數:1 & 1 會是 1

所以,最後的結果就是 1010 也就是 10,因此就是回傳 10

| 位元運算的 or

例如:
輸入 10 | 15 會回傳 15,因為這裡做的是「位元運算」

10 | 15

^ 位元運算的 xor(exclusive or)

兩個東西是一樣的話,就會回傳 0:

  • 兩個都是 1 的話,會回傳 0
  • 兩個都是 0 的話,會回傳 0

兩個東西不一樣的話,就會回傳 1

  • 0, 1 就會回傳 1
  • 1, 0 就會回傳 1

例如:
輸入 10 ^ 15 會回傳 5,因為這裡做的是「位元運算」

10 ^ 15

~ 位元運算的 not

在邏輯運算中,輸入 !15 會回傳 false

但如果是輸入 ~15,會回傳 -16,因為做的是「位元運算」

為什麼會是 -16 呢?

因為把 15 轉成二進位就會是 1111
乍看之下是 1111,但是因為在 JavaScript 的數字是有 32 個 bit
所以,1111 其實是 000000000000000000000000000000001111(前面還有很多很多個 0)

所以把 000000000000000000000000000000001111 做 not 的運算後就會是 111111111111111111111111111111110000 = -16

可以把 & 當作是「位元遮罩」來用

1010 and 1 就會是 0000
1011 and 1 就會是 0001

因為只有「and 1」,前面每個位數的結果都一定會是 0,因此就只需要看最後一個位數

  • 如果最後一個位數是 0,結果就會是 0
  • 如果最後一個位數是 1,結果就會是 1

因此,就可以推導出這樣的公式:
A & 1 => 0 代表「A 的最後一個數字是 0」
A & 1 => 1 代表「A 的最後一個數字是 1」

A & 8 => 8 代表「A 的第四個位數是 1」

因為 8 轉成二進位是 1000,所以只需要看「第四個位數」來決定最後結果(其他位數經過 and 的運算後,都會是 0)

這樣的公式可以用在哪裡?

二進位的每個位數分別代表

1 2 4 8 16 32...

仔細觀察會發現,只有第一個位數是奇數(也就是 1)

所以

如果二進位的最後一個數字是 0 的話,例如 1010,那它轉成十進位後就一定會是「偶數」

因為 1010 轉成十進位會是:
2^0 0 是 0 (唯一有可能是奇數的位數是 0)
加上 2^1
1 (是偶數)
加上 2^2 0 (是 0)
加上 2^3
1 (是偶數)

所以最後的結果就會是 0 + 2 + 0 + 8 = 10(偶數)

如果二進位的最後一個數字是 1 的話,例如 1011,那它轉成十進位後就一定會是「奇數」

因為 1011 轉成十進位會是:
2^0 1 是 1 (唯一有可能是奇數的位數是 1)
加上 2^1
1 (是偶數)
加上 2^2 0 (是 0)
加上 2^3
1 (是偶數)

所以最後的結果就會是 1 + 2 + 0 + 8 = 11(奇數)

那我要怎麼知道「二進位的最後一個數字」是 0 還是 1 呢?

這時,就可以用到上面推導出來的公式:
A 是一個十進位的數字
(在做 & 運算前,電腦會自動先把 A 轉成二進位)

A & 1 => 0 代表「A 的最後一個數字是 0」,那就代表「轉成十進位後,會是一個偶數」

例如:

  • 輸入 38 & 1,會回傳 0 (因為 38 是偶數)
    ### A & 1 => 1 代表「A 的最後一個數字是 1」,那就代表「轉成十進位後,會是一個奇數」
    例如:
  • 輸入 39 & 1,會回傳 1 (因為 39 是奇數)

結論:用「位元運算」,我可以很快的判斷出這個數字是「偶數」還是「奇數」


#node.js







Related Posts

MTR04_0915

MTR04_0915

Gatsby程序化產生頁面

Gatsby程序化產生頁面

串接 API

串接 API


Comments