Number 在 JS 中一種簡單卻值得探索東西,其涵蓋了整數、符點數,甚至是特殊情況(infinity
和NaN
),以下示範:
let intNum = 42;
console.log(intNum); // 輸出: 42
let floatNum = 3.14;
console.log(floatNum); // 輸出: 3.14
let largeNum = 1.23e5; // 1.23 × 10^5
console.log(largeNum); // 輸出: 123000
let positiveInfinity = 1 / 0;
console.log(positiveInfinity); // 輸出: Infinity
let notANumber = 1 / "a";
console.log(notANumber); // 輸出: NaN
NaN
表示 "不是一個數值"以下幾種是非常基本且好懂的:
+
,-
,*
/
, %
=
, +=
,-=
, *=
, /=
,%=
==
, ===
, !=
, !==
, <
, >
, <=
, >=
&&
(AND), ||
(OR), !
(NOT)// 算術運算符
let a = 10;
let b = 3;
console.log(a + b); // 輸出: 13
console.log(a - b); // 輸出: 7
console.log(a * b); // 輸出: 30
console.log(a / b); // 輸出: 3.3333
console.log(a % b); // 輸出: 1
// 賦值運算符
let c = 2;
c *= a + b; // 相當於 c = c * (a + b)
console.log(c); // 輸出: 26
// 比較運算符
console.log(a == b); // 輸出: false
console.log(a === b); // 輸出: false (嚴格相等)
console.log(a != b); // 輸出: true
console.log(a > b); // 輸出: true
// 邏輯運算符
console.log(a > b && b < 5); // 輸出: true
console.log(a < b || b < 5); // 輸出: true
console.log(!(a > b)); // 輸出: false
關於一般相等與嚴格相等,這裡有一個例子:
console.log(5 == "5") // true
console.log(5 === "5") // false
在 JavaScript 中,運算符的優先級決定了表達式中運算符執行的順序。運算符優先級越高,越早執行。而當運算符具有相同優先級時,會根據結合性來決定執行的方向。
一些例子如下:
let result = 2 + 3 * 4;
console.log(result); // 輸出: 14 (先乘法後加法)
let resultWithParentheses = (2 + 3) * 4;
console.log(resultWithParentheses); // 輸出: 20 (括號優先)
let a = 5;
let result = -a + 10;
console.log(result); // 輸出: 5 (先執行負號運算,再執行加法)
let result = 2 ** 3 ** 2;
// 等價於 2 ** (3 ** 2)
console.log(result); // 輸出: 512
let a, b, c;
a = b = c = 5;
// 等價於 a = (b = (c = 5))
console.log(a, b, c); // 輸出: 5 5 5
let result = true || false && false;
// 等價於 true || (false && false)
console.log(result); // 輸出: true
好,目前你對基本的運算符已經有了基本的認識,不過如果今天嘗試使用數字和字串相加會發生甚麼事情呢?
const result = 5 + "10";
console.log(result); // 510
而其他算數運算符的情況則不同,請看以下示範:
const result = 10 - "5";
console.log(result);
console.log(typeof result);
const result2 = 10 * "5";
console.log(result2);
console.log(typeof result2);
const result3 = 10 / "5";
console.log(result3);
console.log(typeof result3);
const result4 = "abc" * 5 / 5 - 5;
console.log(result4);
console.log(typeof result4);
/* 輸出
5
number
50
number
2
number
NaN
number
*/
我們再看看字串、布林值與數字間的運算會發生甚麼事情:
const result = true + 1;
console.log(result);
console.log(typeof result);
const result2 = false + 1;
console.log(result2);
console.log(typeof result2);
const result3 = "hello" + true;
console.log(result3);
console.log(typeof result3);
/* 輸出
2
number
1
number
hellotrue
string
*/
另外,null
和 undefined
的運算情況如下:
const result = null + 1;
console.log(result);
console.log(typeof result);
const result2 = undefined + 1;
console.log(result2);
console.log(typeof result2);
/* 輸出
1
number
NaN
number
*/
好,現在我們提一下後置遞增與遞減以及前置遞增與遞減。
雖然它們的功能都是讓變量的值增加1或減少1,但執行的時機有所不同,這會影響最終表達式的結果。一些範例如下:
let a = 5;
// 前置遞增
let result1 = ++a;
console.log(a); // 6 (變量 a 被先遞增)
console.log(result1); // 6 (表達式返回新值)
// 前置遞減
let b = 5;
let result2 = --b;
console.log(b); // 4 (變量 b 被先遞減)
console.log(result2); // 4 (表達式返回新值)
let x = 5;
// 後置遞增
let result3 = x++;
console.log(x); // 6 (變量 x 被遞增,但在表達式後才生效)
console.log(result3); // 5 (表達式返回原值)
// 後置遞減
let y = 5;
let result4 = y--;
console.log(y); // 4 (變量 y 被遞減,但在表達式後才生效)
console.log(result4); // 5 (表達式返回原值)
let total = 0;
let count = 5;
// 使用後置遞增
total = count++ + 10; // total = 5 + 10
console.log(total); // 15
console.log(count); // 6
// 使用前置遞增
total = ++count + 10; // count 先遞增為 7,然後計算
console.log(total); // 17
console.log(count); // 7
好,接著我要特別提到一元運算子:
在 JavaScript 中,一元運算子只需要操作一個運算元。這些運算子常用來執行簡單的運算,比如數值轉換、正負號變換、邏輯反轉等。
一些例子如下:
一些程式碼例子如下:
console.log(!true); // false
console.log(!0); // true
console.log(!!"text"); // true
console.log(!""); // true
console.log(~5); // -6
console.log(~-1); // 0
~5
的結果是 6
?1. 將 5
表示為二進制
在 JavaScript 中,整數使用 32 位有符號整數表示。5
的二進制表示為:
00000000 00000000 00000000 00000101
2. 逐位取反
使用 ~
後,所有位元都取反:
11111111 11111111 11111111 11111010 // 由於最前面的數字為1,因此這個數字為負的
3. 最後要得出結果的話,要使用一次二的補數轉換規則 ⇒ 原碼的所有位取反後加1。
因此:
11111111 11111111 11111111 11111010 ==> - (00000000 00000000 00000000 00000101 + 1) = -6
所以,~5
的結果是 -6
。
上面這些知識也都是需要知道的基本觀念,好,那接著有了上面對於整數的二進制位元的知識,我們可以接著提到位元運算符。這些運算符會將數字轉換為 32 位有符號整數,並對每一位元進行操作。
常見的位元運算符 ⇒ &
、|
、^
、~
、<<
、>>
、 >>>
一些例子如下:
console.log(5 & 3); // 1
// 5 = 0101 (二進制)(正確應該表示為 00000000 00000000 00000000 00000101,不過前面都是0,所以我們可特別關注最後數字即可)
// 3 = 0011 (二進制)
// 結果 = 0001 (二進制) => 1
console.log(5 | 3); // 7
// 5 = 0101 (二進制)
// 3 = 0011 (二進制)
// 結果 = 0111 (二進制) => 7
console.log(5 ^ 3); // 6
// 5 = 0101 (二進制)
// 3 = 0011 (二進制)
// 結果 = 0110 (二進制) => 6
console.log(5 << 1); // 10
// 5 = 00000000 00000000 00000000 00000101 (二進制)
// 左移 1 位 = 00000000 00000000 00000000 00001010 (二進制)
// 結果 = 10
console.log(5 >> 1); // 2
// 5 = 00000000 00000000 00000000 00000101 (二進制)
// 右移 1 位 = 00000000 00000000 00000000 00000010 (二進制)
// 結果 = 2
console.log(5 >>> 1); // 2
// 5 = 00000000 00000000 00000000 00000101 (二進制)
// 無符號右移 1 位 = 00000000 00000000 00000000 00000010 (二進制)
// 結果 = 2
常見且基本的數字方法如下。
isNaN()
: 檢測值是否為非數值。
// 測試不同情況下 isNaN 的結果
console.log("1. isNaN(123):", isNaN(123)); // false - 123 是數字
console.log("2. isNaN('123'):", isNaN("123")); // false - 字串 '123' 會被轉換為數字
console.log("3. isNaN('123abc'):", isNaN("123abc")); // true - '123abc' 無法轉換為有效數字
console.log("4. isNaN(''):", isNaN("")); // false - 空字串被轉換為 0
console.log("5. isNaN(' '):", isNaN(" ")); // false - 只有空格也被轉換為 0
console.log("6. isNaN(NaN):", isNaN(NaN)); // true - NaN 本身當然是 NaN
console.log("7. isNaN(undefined):", isNaN(undefined)); // true - undefined 不是有效數字
console.log("8. isNaN(null):", isNaN(null)); // false - null 被轉換為 0
console.log("9. isNaN(true):", isNaN(true)); // false - true 被轉換為 1
console.log("10. isNaN(false):", isNaN(false)); // false - false 被轉換為 0
console.log("11. isNaN([]):", isNaN([])); // false - 空陣列被轉換為 0
console.log("12. isNaN([42]):", isNaN([42])); // false - 單元素陣列 42 被轉換為數字 42
console.log("13. isNaN([1, 2]):", isNaN([1, 2])); // true - 多元素陣列無法轉換為有效數字
console.log("14. isNaN({}):", isNaN({})); // true - 物件無法轉換為有效數字
console.log("15. isNaN(Infinity):", isNaN(Infinity)); // false - Infinity 是數字
console.log("16. isNaN(-Infinity):", isNaN(-Infinity)); // false - -Infinity 是數字
console.log("17. isNaN('Infinity'):", isNaN("Infinity")); // false - 字串 'Infinity' 被轉換為數字
// 測試混合情況
console.log("18. isNaN(0/0):", isNaN(0 / 0)); // true - 0/0 結果是 NaN
console.log("19. isNaN('text' / 2):", isNaN("text" / 2)); // true - 無法進行有效的數學運算
console.log("20. isNaN(42 / 0):", isNaN(42 / 0)); // false - 除以 0 結果是 Infinity
// 特殊注意事項:Number.isNaN 和 isNaN 的區別
console.log("21. Number.isNaN('123'):", Number.isNaN("123")); // false - 不會進行類型轉換
parseInt()
和 parseFloat()
:將字串轉為整數或符點數。
// parseInt 基本範例
console.log(parseInt("42")); // 42 - 將字串轉換為整數
console.log(parseInt("42.99")); // 42 - 僅保留整數部分
console.log(parseInt(" 42abc")); // 42 - 忽略開頭空白,直到遇到無法解析的字元
console.log(parseInt("abc42")); // NaN - 開頭無法解析成數字
// parseFloat 基本範例
console.log(parseFloat("42.99")); // 42.99 - 完整轉換為浮點數
console.log(parseFloat(" 42.99")); // 42.99 - 忽略開頭空白
console.log(parseFloat("42.99abc")); // 42.99 - 解析數字部分後停止
console.log(parseFloat("abc42.99"));// NaN - 開頭無法解析成數字
toFixed()
:用於格式化數字,控制數字中的小數位數,它返回字串的表示形式。
let result = 0.1 + 0.26;
console.log(result.toFixed(1)); // 輸出: "0.4"
console.log(result.toFixed(2)); // 輸出: "0.36"
console.log(typeof result.toFixed(2)); // 輸出: string
JS 中提供了一個內置的數學對象來處理更負責的數學挑戰。這個方便的工具提供許多方法執行各種操作計算。
Math.random()
: 返回介於 0(包含)和 1(不包含)之間的隨機數,例如Math.random()
→ 0.345
。Math.abs(x)
: 返回數字的絕對值,例如Math.abs(-5)
→ 5
Math.ceil(x)
: 返回大於或等於 x 的最小整數(向上取整),例如Math.ceil(4.2)
→ 5
Math.floor(x)
: 返回小於或等於 x 的最大整數(向下取整),例如Math.floor(4.8)
→ 4
Math.round(x)
: 返回最接近 x 的整數(四捨五入),例如Math.round(4.5)
→ 5
Math.sqrt(x)
: 返回 x 的平方根,例如Math.sqrt(16)
→ 4
Math.pow(x, y)
: 返回 x 的 y 次方(x^y),例如Math.pow(2, 3)
→ 8
Math.max(x, y, ...)
: 返回參數中的最大值,例如Math.max(1, 2, 3)
→ 3
Math.min(x, y, ...)
: 返回參數中的最小值,例如Math.min(1, 2, 3)
→ 1
Math.random()
應用範例:
// 生成 1 到 100 的隨機整數
let randomNumber = Math.floor(Math.random() * 100) + 1;
console.log(`隨機數: ${randomNumber}`);