人人都愛數學
好吧,也許不是。我們中的一些人喜歡數學,另一些人自從在學校學習乘法表和長除法後就討厭數學,還有一些人介於兩者之間。但我們誰也不能否認,數學是生活中不可或缺的一部分,沒有它我們寸步難行。當我們學習 JavaScript(或任何其他語言)程式設計時尤其如此——我們所做的很多事情都依賴於處理數值資料、計算新值等等,所以當你瞭解到 JavaScript 擁有一整套功能齊全的數學函式時,你不會感到驚訝。
本文只討論你現在需要了解的基礎部分。
數值的型別
在程式設計中,即使是我們都熟知的普通十進位制數系統,也比你想象的要複雜。我們用不同的術語來描述不同型別的十進位制數,例如:
- 整數是沒有小數部分的數。它們可以是正數或負數,例如 10、400 或 -5。
- 浮點數(floats)有小數點和小數位,例如 12.5 和 56.7786543。
我們甚至有不同型別的數制!十進位制是基數為 10(意味著每位使用 0-9),但我們還有類似以下的數制:
- 二進位制——計算機的最低階語言;0 和 1。
- 八進位制——基數為 8,每位使用 0-7。
- 十六進位制——基數為 16,每位使用 0-9 然後是 a-f。你可能在 CSS 中設定顏色時遇到過這些數。
在你開始擔心大腦要融化之前,請就此打住!首先,在本課程中,我們將只使用十進位制數;你很少會需要考慮其他型別的數,如果真的有的話。
第二個好訊息是,與其他一些程式語言不同,JavaScript 只有一種數值資料型別,用於表示整數和浮點數——你猜對了,就是 Number。這意味著無論你在 JavaScript 中處理何種型別的數值,處理它們的方式都完全相同。
備註:實際上,JavaScript 還有第二種數值型別,BigInt,用於表示非常非常大的整數。但就本課程而言,我們只需關心 Number 型別的值。
對我來說都是數值
讓我們快速地玩一下數值,以重新熟悉我們需要的基本語法。在你的瀏覽器開發者工具的 JavaScript 控制檯中輸入下面列出的命令。
-
首先,讓我們宣告幾個變數,並分別用一個整數和一個浮點數來初始化它們,然後重新輸入變數名以檢查一切是否正常:
jsconst myInt = 5; const myFloat = 6.667; myInt; myFloat; -
數值在輸入時不需要引號——在繼續之前,嘗試宣告並初始化另外幾個包含數值的變數。
-
現在讓我們檢查一下我們最初的兩個變數是否是相同的資料型別。JavaScript 中有一個名為
typeof的運算子可以做到這一點。如下所示輸入以下兩行:jstypeof myInt; typeof myFloat;兩種情況下都應該返回
"number"——這比不同型別的數值有不同的資料型別,需要用不同方式處理要簡單得多。太好了!
有用的 Number 方法
Number 物件的一個例項代表了你在 JavaScript 中會用到的所有標準數值,它上面有許多有用的方法可以用來運算元值。我們在本文中不會詳細介紹這些方法,因為我們希望將其作為入門介紹,目前只涵蓋真正的基礎知識;但是,在你讀完這個模組幾次後,值得去檢視物件參考頁面,瞭解更多可用的方法。
例如,要將你的數值四捨五入到固定的小數位數,請使用 toFixed() 方法。在你的瀏覽器的控制檯中輸入以下幾行:
const lotsOfDecimal = 1.7665849587;
lotsOfDecimal;
const twoDecimalPlaces = lotsOfDecimal.toFixed(2);
twoDecimalPlaces;
轉換為數值資料型別
有時你可能會遇到以字串型別儲存的數值,這使得對其進行計算變得困難。這最常發生在資料被輸入到表單輸入框中,且輸入框型別為文字時。有一個解決方法——將字串值傳入 Number() 建構函式,以返回相同值的數值版本。
例如,嘗試在你的控制檯中輸入這些行:
let myNumber = "74";
myNumber += 3;
你得到的結果是 743,而不是 77,因為 myNumber 實際上被定義為一個字串。你可以透過輸入以下內容來測試:
typeof myNumber;
要修復這個計算,你可以這樣做:
let myNumber = "74";
myNumber = Number(myNumber) + 3;
結果就是 77,如最初預期的那樣。
算術運算子
算術運算子用於在 JavaScript 中執行數學計算。
| 運算子 | 名稱 | 用途 | 示例 |
|---|---|---|---|
+ |
加法 | 將兩個數相加。 | 6 + 9 |
- |
減法 | 左邊的數減去右邊的數。 | 20 - 15 |
* |
乘法 | 將兩個數相乘。 | 3 * 7 |
/ |
除法 | 左邊的數除以右邊的數。 | 10 / 5 |
% |
餘數(有時稱為模) |
返回左邊的數除以右邊的數後,剩餘的餘數。 |
|
** |
冪 | 將一個底數提升到指數次冪,即底數自乘指數次。 |
5 ** 2(返回 25,與 5 * 5 相同)。 |
備註:你有時會看到參與算術運算的數被稱為運算元。
備註:你有時可能會看到使用舊的 Math.pow() 方法來表示冪運算,它的工作方式非常相似。例如,在 Math.pow(7, 3) 中,7 是底數,3 是指數,所以表示式的結果是 343。Math.pow(7, 3) 等同於 7**3。
我們可能不需要教你如何做基礎數學,但我們想測試你對所涉及語法的理解。嘗試在你的開發者工具的 JavaScript 控制檯中輸入以下示例,以熟悉語法。
-
首先嚐試輸入一些你自己的簡單示例,例如:
js10 + 7; 9 * 8; 60 % 3; -
你也可以嘗試在變數中宣告和初始化一些數值,並嘗試在求和中使用它們——在求和中,這些變數的行為將完全等同於它們所持有的值。例如:
jsconst num1 = 10; const num2 = 50; 9 * num1; num1 ** 3; num2 / num1; -
本節最後,嘗試輸入一些更復雜的表示式,例如:
js5 + 10 * 3; (num2 % 9) * num1; num2 + num1 / 8 + 2;
最後一組計算的某些部分可能沒有給你預期的結果;下面的部分很可能會解釋為什麼。
運算子優先順序
讓我們看一下上面最後一個例子,假設 num2 的值是 50,num1 的值是 10(如上文最初所述):
num2 + num1 / 8 + 2;
作為人類,你可能會將其讀作“50 加 10 等於 60”,然後“8 加 2 等於 10”,最後“60 除以 10 等於 6”。
但瀏覽器會先算“10 除以 8 等於 1.25”,然後“50 加 1.25 加 2 等於 53.25”。
這是因為運算子優先順序——在計算一個計算結果(在程式設計中稱為表示式)時,某些運算子會比其他運算子先被應用。JavaScript 中的運算子優先順序與學校數學課上教的一樣——乘法和除法總是先做,然後是加法和減法(計算總是從左到右進行)。
如果你想覆蓋運算子優先順序,你可以用括號括起你希望優先處理的部分。所以要得到結果 6,我們可以這樣做:
(num2 + num1) / (8 + 2);
嘗試在控制檯中輸入上一行來測試一下。
備註:所有 JavaScript 運算子及其優先順序的完整列表可以在運算子優先順序中找到。
遞增和遞減運算子
有時你會想對一個數值變數重複地加一或減一。這可以方便地使用遞增 (++) 和遞減 (--) 運算子來完成。我們在初探 JavaScript 文章中的“猜數字”遊戲中使用了 ++,當時我們給 guessCount 變數加 1,以跟蹤使用者每輪後還剩下多少次猜測機會。
guessCount++;
讓我們在你的控制檯中試一下這些。首先,請注意你不能將它們直接應用於一個數,這可能看起來很奇怪,但我們是在給一個變數賦一個新的更新值,而不是對值本身進行操作。以下程式碼會返回一個錯誤:
3++;
所以,你只能遞增一個已存在的變數。試試這個:
let num1 = 4;
num1++;
好了,第二個奇怪之處!當你這樣做時,你會看到返回值為 4——這是因為瀏覽器會返回當前值,然後再遞增變數。如果你再次返回變數的值,你就會看到它已經被遞增了:
num1;
-- 也是如此:嘗試以下程式碼:
let num2 = 6;
num2--;
num2;
備註:你可以讓瀏覽器反過來做——先遞增/遞減變數,然後再返回值——方法是將運算子放在變數的開頭而不是末尾。再次嘗試上面的例子,但這次使用 ++num1 和 --num2。
賦值運算子
賦值運算子是給變數賦值的運算子。我們已經多次使用了最基本的一個,=——它將右邊的值賦給左邊的變數:
let x = 3; // x contains the value 3
let y = 4; // y contains the value 4
x = y; // x now contains the same value y contains, 4
但還有一些更復雜的型別,它們提供了有用的快捷方式,使你的程式碼更整潔、更高效。最常見的如下所示:
| 運算子 | 名稱 | 用途 | 示例 | 快捷方式 |
|---|---|---|---|---|
+= |
加法賦值 | 將右邊的值加到左邊變數的值上,然後返回新的變數值 | x += 4; |
x = x + 4; |
-= |
減法賦值 | 從左邊變數的值中減去右邊的值,並返回新的變數值 | x -= 3; |
x = x - 3; |
*= |
乘法賦值 | 將左邊變數的值乘以右邊的值,並返回新的變數值 | x *= 3; |
x = x * 3; |
/= |
除法賦值 | 將左邊變數的值除以右邊的值,並返回新的變數值 | x /= 5; |
x = x / 5; |
嘗試在你的控制檯中輸入一些上面的例子,以瞭解它們是如何工作的。在每種情況下,看看你是否能在輸入第二行之前猜出值是多少。
注意,你完全可以在每個表示式的右側使用其他變數,例如:
let x = 3; // x contains the value 3
let y = 4; // y contains the value 4
x *= y; // x now contains the value 12
備註:還有許多其他可用的賦值運算子,但這些是你現在應該學習的基礎。
調整畫布盒子的大小
在這個練習中,你將操作一些數值和運算子來改變一個盒子的大小。這個盒子是使用一個名為 Canvas API 的瀏覽器 API 繪製的。無需擔心它是如何工作的——現在只需專注於數學部分。盒子的寬度和高度(以畫素為單位)由變數 x 和 y 定義,它們最初都被賦予了 50 的值。
const canvas = document.getElementById("canvas");
const para = document.querySelector("p");
const ctx = canvas.getContext("2d");
// Edit the following two lines ONLY
let x = 50;
let y = 50;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "green";
ctx.fillRect(10, 10, x, y);
para.textContent = `The rectangle is ${x}px wide and ${y}px high.`;
透過點選“執行”按鈕在 MDN Playground 中開啟以上示例,然後按照下面的說明列表,在每種情況下使用特定的運算子和/或值,使盒子放大/縮小到特定尺寸:
- 更改計算
x的那一行,使盒子的寬度仍然是50px,但是 50 是使用數字 43 和 7 以及一個算術運算子計算出來的。 - 更改計算
y的那一行,使盒子的高度是75px,但是 75 是使用數字 25 和 3 以及一個算術運算子計算出來的。 - 更改計算
x的那一行,使盒子的寬度是100px,但是 100 是使用三個數字以及減法和除法運算子計算出來的。 - 更改計算
y的那一行,使盒子的高度是200px,但是 200 是使用數字 2 和x以及乘法運算子計算出來的。
如果把程式碼弄亂了也不用擔心。你隨時可以按下“重置”按鈕重新開始。
比較運算子
有時我們會想執行真/假測試,然後根據測試的結果採取相應的行動——要做到這一點,我們使用比較運算子。
| 運算子 | 名稱 | 用途 | 示例 |
|---|---|---|---|
=== |
嚴格相等 | 測試左值和右值是否完全相同 | 5 === 2 + 4 |
!== |
嚴格不相等 | 測試左值和右值是否不完全相同 | 5 !== 2 + 3 |
< |
小於 | 測試左值是否小於右值。 | 10 < 6 |
> |
大於 | 測試左值是否大於右值。 | 10 > 20 |
<= |
小於或等於 | 測試左值是否小於或等於右值。 | 3 <= 2 |
>= |
大於或等於 | 測試左值是否大於或等於右值。 | 5 >= 4 |
備註:你可能會看到一些人在他們的相等和不相等測試中使用 == 和 !=。這些在 JavaScript 中是有效的運算子,但它們與 ===/!== 不同。前一種版本測試值是否相同,但不測試值的資料型別是否相同。後一種嚴格版本則同時測試值和資料型別的相等性。嚴格版本往往能減少錯誤,所以我們推薦你使用它們。
如果你嘗試在控制檯中輸入其中一些值,你會看到它們都返回 true/false 值——就是我們在上一篇文章中提到的布林值。這些非常有用,因為它們允許我們在程式碼中做決策,並且每當我們想做某種選擇時都會用到它們。例如,布林值可以用來:
- 根據某個功能是開啟還是關閉,在按鈕上顯示正確的文字標籤
- 如果遊戲結束則顯示遊戲結束訊息,如果遊戲獲勝則顯示勝利訊息
- 根據是什麼節日季節顯示正確的季節性問候
- 根據選擇的縮放級別放大或縮小地圖
我們將在未來的文章中學習條件語句時,看看如何編寫這樣的邏輯。現在,讓我們看一個快速的例子:
<button>Start machine</button>
<p>The machine is stopped.</p>
const btn = document.querySelector("button");
const txt = document.querySelector("p");
btn.addEventListener("click", updateBtn);
function updateBtn() {
if (btn.textContent === "Start machine") {
btn.textContent = "Stop machine";
txt.textContent = "The machine has started!";
} else {
btn.textContent = "Start machine";
txt.textContent = "The machine is stopped.";
}
}
你可以在 updateBtn() 函式內部看到相等運算子的使用。在這種情況下,我們不是在測試兩個數學表示式的值是否相同——我們是在測試按鈕的文字內容是否包含某個特定的字串——但其工作原理是相同的。如果按鈕在被按下時當前顯示“啟動機器”,我們會將其標籤更改為“停止機器”,並相應地更新標籤。如果按鈕在被按下時當前顯示“停止機器”,我們會將顯示切換回來。
備註:這種在兩種狀態之間切換的控制元件通常被稱為開關(toggle)。它在一種狀態和另一種狀態之間切換——燈開,燈關,等等。
總結
在本文中,我們已經涵蓋了你目前需要了解的關於 JavaScript 中數值的基礎資訊。在你的 JavaScript 學習過程中,你會一次又一次地看到數值的使用,所以現在把這部分搞清楚是個好主意。如果你是那些不喜歡數學的人之一,你可以感到欣慰的是,這一章相當簡短。
在下一篇文章中,我們將提供一些測試,你可以用它們來檢查你對這些資訊的理解和掌握程度。