【JavaScript 學習筆記 01】基本概念 Chapter 1 Values, Types, and Operators
本系列內容是基於 Eloquent JavaScript 4th edition (2024) 所整理的精簡筆記。
The best programs are those that manage to do something interesting while still being easy to understand.
數字(Numbers)
JavaScript 中的數字型別是基於 64 位元的雙精度浮點數格式(IEEE 754),能表示極大的數值範圍。整數計算通常是精確的,但小數計算可能因精度限制而產生誤差。因此,理解 JavaScript 對數字的處理方式,尤其是小數的限制,是正確進行數值運算的基礎。
1. 數字的精度問題
1.1 整數的精度範圍
JavaScript 的數字型別 Number
能夠表示的整數範圍是 ±2^53
,在此範圍內的整數計算通常是精確的。
1.2 小數的精度限制
小數計算可能產生誤差,因為許多數字(例如:π
或 0.1
)無法用有限的位元精確表示。這是由 IEEE 754 標準的雙精度浮點數格式所導致的。
注意:小數應被視為「近似值」而非「精確值」,這種精度損失通常只在特定情況下造成實際問題。
2. 特殊數值
JavaScript 中有三個特殊的數值類型,它們屬於 Number
型別,但行為與普通數字不同:
2.1 Infinity 及 -Infinity
Infinity
表示正無窮大,-Infinity
表示負無窮大。- 任何數與
Infinity
相加或相減,結果仍為Infinity
。例如:javascriptconsole.log(Infinity - 1); // → Infinity
- 注意:
Infinity
是一個數值型別,但在數學上並不合理,因此應避免依賴Infinity
的計算結果。
2.2 NaN(Not a Number)
NaN
是一個特殊的數值,表示「不是一個數字」。- 它通常出現於無意義的數值運算中,例如:
javascript
console.log(0 / 0); // → NaN console.log(Infinity - Infinity); // → NaN
- 特性:
NaN
是唯一一個不等於自身的值:javascriptconsole.log(NaN === NaN); // → false
字串(Strings)
JavaScript 的字串型別是基於 Unicode 標準,用於表示和操作文本數據。字串可以使用以下三種引號來標記,只需確保開頭與結尾的引號類型匹配即可。
`我是字串`
'我是字串'
"我是字串"
1. 字串的基本用法
1.1 定義字串
- 單引號、雙引號和反引號都可以用來定義字串:
javascript
let single = '這是單引號字串'; let double = "這是雙引號字串"; let template = `這是反引號字串`;
- 注意:反引號字串(模板字串)支持嵌入變數與多行文本,這是其特有的功能。
javascript
let name = "Alice"; console.log(`Hello, ${name}`); // → Hello, Alice
1.2 字串的不可變性
JavaScript 的字串是不可變的,這意味著一旦創建,字串的內容無法被修改。如果需要更改字串,必須創建一個新的字串:
let str = "Hello";
str[0] = "h"; // 無效操作
console.log(str); // → Hello
2. 特殊字符處理
在處理包含特殊字符或嵌套引號的字串時,可能會遇到語法錯誤。以下是常見情況及解決方法。
2.1 引號嵌套
當字串中包含與外層引號相同的引號時,JavaScript 會將內部的引號視為字串的結束符,導致語法錯誤。
- 解決方法 1:使用不同類型的引號嵌套
可以使用單引號和雙引號搭配,避免衝突。javascriptconsole.log('He said "Hello"'); // → He said "Hello" console.log("It's a sunny day"); // → It's a sunny day
- 解決方法 2:使用跳脫字元(
\
)
使用反斜線(\
)作為跳脫字元,讓內部的引號被視為字串的一部分而非結束符。javascriptconsole.log("He said \"Hello\""); // → He said "Hello" console.log('It\'s a sunny day'); // → It's a sunny day
2.2 常見的跳脫字符
除了跳脫引號,JavaScript 還支持其他特殊字符的跳脫,以下是一些常見的例子:
跳脫字符 | 說明 | 範例 |
---|---|---|
\' | 單引號 | 'It\'s a sunny day' |
\" | 雙引號 | "He said \"Hello\"" |
\\ | 反斜線 | 'This is a backslash: \\' |
\n | 換行符 | 'Line 1\nLine 2' |
\t | 製表符 | 'Column1\tColumn2' |
3. 字串的 Unicode 支援
JavaScript 的字串基於 Unicode,這意味著它可以表示幾乎所有的文字字符。然而某些特殊字符(例如表情符號或罕見的 Unicode 字元)需要特別處理。
3.1 使用 Unicode 編碼
可以通過 \u
或 \x
來表示特殊字符:
console.log('\u2764'); // → ❤
console.log('\u{1F600}'); // → 😀 (需要 ES6 支援)
3.2 字串長度與編碼單位
JavaScript 的 length
屬性基於 UTF-16 編碼單位,而非實際字符數。例如:
let emoji = "😀";
console.log(emoji.length); // → 2 (UTF-16 編碼單位)
運算子(Operators)
JavaScript 中的運算子根據操作數的數量分為以下三種:
- 單元運算子(Unary Operators):只使用一個值。
- 二元運算子(Binary Operators):使用兩個值。
- 三元運算子(Ternary Operator):使用三個值(後續會介紹)。
1. 單元運算子(Unary Operators)
單元運算子只需要一個操作數。以下是常見的單元運算子:
1.1 typeof
用於檢查值的類型,返回一個表示類型的字串。
console.log(typeof 4.5); // → "number"
console.log(typeof "Hello"); // → "string"
1.2 !(邏輯非運算子)
用於反轉布林值。
console.log(!true); // → false
console.log(!false); // → true
1.3 -(負號運算子)
用於將數字取負值。
console.log(-10); // → -10
console.log(-(-10)); // → 10
2. 二元運算子(Binary Operators)
二元運算子需要兩個操作數。以下是常見的二元運算子分類:
2.1 算術運算子
用於數值計算:
console.log(10 + 5); // → 15
console.log(10 % 3); // → 1
2.2 比較運算子
用於比較兩個值,返回布林值:
==
(相等,會進行類型轉換)===
(全等,不進行類型轉換)!=
(不相等,會進行類型轉換)!==
(不全等,不進行類型轉換)>
、<
、>=
、<=
console.log(10 > 5); // → true
console.log(10 === "10"); // → false
console.log(10 == "10"); // → true
2.3 邏輯運算子
用於布林值的邏輯運算:&&
(and)、||
(or)。
console.log(true && false); // → false
console.log(true || false); // → true
2.4 賦值運算子
用於將值賦給變數:=
、+=
、-=
、*=
、/=
。
let x = 10;
x += 5; // 相當於 x = x + 5
console.log(x); // → 15
3. 特殊運算子 -
的雙重角色
-
是一個特殊的運算子,既可以作為單元運算子,也可以作為二元運算子:
3.1 作為單元運算子
用於取負值:
console.log(-10); // → -10
3.2 作為二元運算子
用於數值減法:
console.log(10 - 2); // → 8
3.3 混合使用
單元與二元運算子可以在同一表達式中使用:
console.log(- (10 - 2)); // → -8
布林值(Boolean values)
JavaScript 的布林類型只有兩個值,true
和 false
。這些值通常用於判斷條件是否成立,並控制程式的執行流程。
1. 比較運算符(Comparison Operators)
比較運算符用於比較兩個值,結果為布林值 true
或 false
。
1.1 常見比較運算符
>
、<
、>=
、<=
、==
、!=
console.log(3 > 2); // → true
console.log(3 < 2); // → false
console.log("Garnet" != "Ruby"); // → true
console.log("Pearl" == "Amethyst"); // → false
1.2 特殊情況:NaN
NaN
是唯一不等於自身的值。
console.log(NaN == NaN); // → false
2. 邏輯運算符(Logical Operators)
邏輯運算符用於組合布林值,結果仍為布林值。主要包括以下三種:
2.1 邏輯運算符列表
&&
(邏輯與,AND)
當兩個操作數皆為true
時,結果為true
;否則為false
。javascriptconsole.log(true && false); // → false console.log(true && true); // → true
||
(邏輯或,OR)
當至少一個操作數為true
時,結果為true
;否則為false
。javascriptconsole.log(false || true); // → true console.log(false || false); // → false
!
(邏輯非,NOT)
用於反轉布林值。javascriptconsole.log(!true); // → false console.log(!false); // → true
2.2 邏輯運算真值表
運算符 | 條件 1 | 條件 2 | 結果 |
---|---|---|---|
&& | true | true | true |
&& | true | false | false |
&& | false | true | false |
&& | false | false | false |
|| | true | true | true |
|| | true | false | true |
|| | false | true | true |
|| | false | false | false |
! | true | - | false |
! | false | - | true |
3. 運算符優先級
在複雜的表達式中,運算符的執行順序由其優先級決定。以下是常見運算符的優先級(從低到高):
||
&&
- 比較運算符(如
>
、<
、==
等) - 算術運算符(如
+
、-
、*
、/
等)
範例
console.log(1 + 1 == 2 && 10 * 10 > 50);
// → true
解析:
1 + 1 == 2
先計算加法,結果為true
。10 * 10 > 50
計算乘法,結果為true
。true && true
,結果為true
。
4. 條件運算符(Ternary Operator)
條件運算符是 JavaScript 唯一的三元運算符,用於簡化條件判斷。語法如下:
- 語法:
條件 ? 表達式1 : 表達式2
- 若條件為
true
,則結果為表達式1
; - 若條件為
false
,則結果為表達式2
。
- 若條件為
console.log(true ? 1 : 2); // → 1
console.log(false ? 1 : 2); // → 2
應用場景
條件運算符常用於簡化 if-else
判斷:
let age = 18;
let status = age >= 18 ? "成人" : "未成年";
console.log(status); // → 成人
空值(Empty values)
JavaScript 中的空值類型包括 null
和 undefined
,用於表示「不存在」或「未定義」的值。
null
:明確表示一個空值,通常用於指示「有意義的空值」。undefined
:表示變數尚未賦值,或者對不存在的屬性進行訪問時的結果。
let age = null; // 明確表示 age 沒有值
console.log(age); // → null
let name;
console.log(name); // → undefined (變數未賦值)
自動型別轉換(Automatic type conversion)
當運算符應用於不符合預期類型的值時,JavaScript 會嘗試將值轉換為所需類型,這種行為稱為隱式型別轉換。雖然方便,但可能導致意料之外的結果。
console.log(8 * null); // → 0 (null 被轉換為 0)
console.log("5" - 1); // → 4 ("5" 被轉換為數字 5)
console.log("5" + 1); // → "51" (數字 1 被轉換為字串 "1" 並進行字串拼接)
console.log("five" * 2); // → NaN ("five" 無法轉換為數字)
console.log(false == 0); // → true (false 被轉換為 0)
1. 型別轉換規則
1.1 +
的特性
- 字串與數字混合時,
+
優先執行字串拼接。 - 其他運算符(如
-
、*
)會將字串轉換為數字。
1.2 NaN
的行為
- 無法轉換為數字的值(如
"five"
或undefined
)會變為NaN
。 - 前面有提到,
NaN
是一個特殊值,與任何值比較都返回false
,包括與自身的比較。javascriptconsole.log(NaN == NaN); // → false
2. 比較運算中的類型轉換
2.1 ==
和 ===
的區別
==
:允許類型轉換,並根據一套複雜的規則比較值。===
:不進行類型轉換,僅在類型與值都相等時返回true
。
console.log(0 == false); // → true (型別轉換發生)
console.log(0 === false); // → false (類型不同)
console.log("" == false); // → true (型別轉換發生)
console.log("" === false); // → false (類型不同)
2.2 特殊情況:null 和 undefined
null
和 undefined
只在相互比較時返回 true
,在其他情況下不等於任何值:
console.log(null == undefined); // → true
console.log(null == 0); // → false
2.3 避免型別轉換的建議
儘量使用 ===
和 !==
,避免因型別轉換導致意外行為。
邏輯運算符的短路行為(Short-Circuiting)
邏輯運算符(||
、&&
和 ??
)在運算時具有「短路」特性,根據條件的布林值決定是否執行右側運算。
1. ||
若左側值為「真值」(truthy),直接返回左側值;否則返回右側值。
console.log(null || "user"); // → "user" (左側為 null,轉換為 false)
console.log("Agnes" || "user"); // → "Agnes" (左側為非空字串,轉換為 true)
console.log(0 || -1); // → -1 (0 轉換為 false)
console.log("" || "!?"); // → "!?" (空字串轉換為 false)
2. &&
若左側值為「假值」(falsy),直接返回左側值;否則返回右側值。
console.log(null && "user"); // → null (左側為 null,轉換為 false)
console.log("Agnes" && "user"); // → "user" (左側為 true,返回右側)
console.log(0 && -1); // → 0 (0 轉換為 false)
console.log("Hello" && "World");// → "World" (左側為 true,返回右側)
3. ??(Nullish Coalescing Operator)
- 與
||
類似,但僅在左側值為null
或undefined
時返回右側值。 - 適用於處理空值而不誤判
0
或""
等有效值。
console.log(0 || 100); // → 100 (0 被視為 false)
console.log(0 ?? 100); // → 0 (0 不等於 null 或 undefined)
console.log(null ?? 100); // → 100
延伸閱讀:Nullish coalescing operator (??) - JavaScript - MDN Web Docs
4. 短路行為應用場景
4.1 提供預設值
const username = null; || "Guest"
console.log(username); // → "Guest"
4.2 避免不必要的計算
const shouldRun = false;
shouldRun && expensiveFunction(); // expensiveFunction 不會被執行
總結
- 類型轉換
JavaScript 的自動類型轉換提供靈活性,但可能導致預期外的結果。為避免潛在問題,建議優先使用嚴格比較運算符(===
和!==
)來確保類型與值的精確匹配。 - 邏輯運算符的應用
||
和&&
適用於多種類型,並透過短路行為簡化條件判斷與預設值設定。- 使用
??
處理空值時更加精準,可避免將有效值如0
或""
誤判為空值。
- 運算符優先級
理解運算符的優先級能幫助書寫更清晰、正確的表達式,避免不必要的錯誤與混淆。
以上內容是基於 1. Values, Types, and Operators - Eloquent JavaScript 4th edition (2024) 所整理的精簡筆記。