National Taiwan University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

1

Local AI

--

Uedu Code

--

台灣大學 AQI 67 24°C PM2.5 11
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 05

運算子

算術、比較、邏輯運算子與 == 和 ===
Interaction實作 20 minute(s)

Learning Objectives

  • 說明運算式、運算子與運算元的關係,使用算術、指定與遞增遞減運算子
  • 用比較運算子比較數字與字串,說明 == 與 === 的差別,並一律使用 ===
  • 說明 &&、|| 的短路求值與回傳值,用 ?? 與 ?. 處理沒有值的情況
  • 依運算子優先順序預測運算式的結果,必要時用括號表達意圖

運算式、運算子與運算元

運算式(expression)是一段會算出一個值的程式碼,例如 x + 1。裡面的 + 是運算子(operator), x 和 1 是被運算的運算元(operand)。依照運算元的數量分成三種:

種類 運算元 例子
一元運算子 1 個 -x、!ok、x++、typeof x
二元運算子 2 個 x + y、a === b、a && b
三元運算子(條件運算子) 3 個 score >= 60 ? '及格' : '不及格'

x = x + 1 是合法的運算式;x = 1 + 少了一個運算元,是語法錯誤。這一課依序介紹算術、比較(關係)與邏輯運算子。

算術與指定運算子

運算子 意思 例子 結果
+ - * / 加減乘除 7 / 5 1.4(不會只取整數)
% 餘數 7 % 5 2
** 次方(ES2016) 2 ** 3 8
+= -= *= /= %= 運算後指定回去 a += 5 等於 a = a + 5

+ 是唯一會處理字串的算術運算子:只要有一邊是字串,就變成字串連接,'7' + 5 是 '75'。 其他算術運算子會把字串轉成數字:'7' - 5 是 2、'7' * '2' 是 14,轉不成數字就是 NaN。

算術運算子與字串

投影片 Lab01 的延伸。第 4 行是 9÷3(1+2) 的寫法;第 6、7 行比較 + 和其他運算子遇到字串時的差別。最後看 a 經過 += 與 %= 之後變成多少。

++ 放前面與放後面

x++ 和 ++x 都會讓變數加 1,差別在運算式本身的值:放後面先取原本的值再加,放前面先加再取值。看第 3 行與第 7 行執行後,右邊 y 和 n 的值。

比較運算子:== 與 ===

比較運算子的結果一定是布林值 true 或 false:>、<、>=、<=、==、!=、===、!==。 注意 = 是指定,==、=== 才是比較。

=== 嚴格相等 == 寬鬆相等
型別不同時 直接 false 先轉換型別再比較
2 === '2' / 2 == '2' false true
0 === false / 0 == false false true
null === undefined / null == undefined false true

== 的轉換規則很多,結果常出乎意料('' == 0 是 true、[] == false 也是 true)。一律使用 === 和 !==, 需要轉換時自己先轉(例如 Number(input) === 6),程式的意思才清楚。

其他比較的規則:

  • 字串和字串比較時,依字元的 Unicode 編碼逐字比較(字典順序):'apple' < 'banana' 是 true,但 '10' < '9' 也是 true(先比 '1' 和 '9')。要比大小的數字,記得先轉成數字。
  • NaN 和任何值比較都是 false。
  • in 檢查物件有沒有某個屬性名稱,對陣列檢查的是索引:0 in ['a'] 是 true,'a' in ['a'] 卻是 false。要檢查陣列有沒有某個值,用 arr.includes('a')。
  • instanceof 檢查物件是不是某個類別建立的,例如 new Date() instanceof Date 是 true(j27、j28 會介紹)。

比較運算子

投影片 Lab02 的題目都在這裡。每一行左右兩個結果對照著看:差別通常就在 == 和 ===。

互動:== 和 === 是怎麼比的

先選 A 再選 B,看 A === B、A == B 的結果,以及 == 一步一步把型別轉換成什麼。試試這幾組:1 和 "1"、0 和 ""、null 和 undefined、null 和 0、[1, 2] 和 "1,2"。

想一想:算術與比較

1.

下面的程式會印出什麼?

console.log('3' + 2, '3' - 2);
2.

下面的程式會印出什麼?

let i = 1;
const j = i++ + ++i;
console.log(i, j);
3.

下面的程式會印出什麼?

console.log('10' < '9', 10 < '9');
第 1 次作答

邏輯運算子與短路求值

  • a && b:而且(and),兩邊都是 true,結果才是 true
  • a || b:或者(or),至少一邊是 true,結果就是 true
  • !a:不是(not),把 true 變成 false、false 變成 true

兩個重要的細節:

  1. 短路求值(short-circuit evaluation):&& 的左邊已經是 false,結果一定是 false,右邊根本不會執行;|| 的左邊已經是 true,右邊也不會執行。
  2. &&、|| 回傳的是其中一個運算元本身,不一定是 true/false:
    • a && b:a 是 falsy 就回傳 a,否則回傳 b。所以 2 && 1 是 1、0 && 2 是 0
    • a || b:a 是 truthy 就回傳 a,否則回傳 b。所以 0 || 2 是 2,常用來設定預設值

falsy 是「放進 if 會被當成 false」的值,只有這幾個:false、0、-0、0n、''(空字串)、null、undefined、NaN。 其他的值都是 truthy,包括 '0'、'false'、[]、{}。!!x 可以把任何值轉成對應的布林值。

&& 與 || 的回傳值與短路

前三行對應投影片的邏輯運算子表。後半段的 sayHi 每被呼叫一次,就會印出一行字:第 11~13 行各寫了一次 sayHi(),播放時注意它實際被呼叫了幾次。

?? 與 ?.:處理「沒有值」

用 || 設定預設值有一個問題:0、'' 也是 falsy,會被當成「沒有值」而換成預設值。 ES2020 加入了兩個運算子,專門處理 null 和 undefined:

運算子 意思 例子
a ?? b 空值合併:a 是 null 或 undefined 才用 b 0 ?? 50 是 0(用 || 會得到 50)
obj?.prop 可選串連:obj 是 null 或 undefined 時直接得到 undefined,不會出錯 user.address?.city

沒有 ?. 時,user.address.city 在 address 是 null 時會出現 TypeError: Cannot read properties of null。

條件(三元)運算子 條件 ? 值1 : 值2:條件成立得到值1,否則得到值2,適合「二選一」的簡短判斷。

?? 、?. 與三元運算子

settings.volume 是 0(使用者把音量調成靜音)。比較第 4、5 行:|| 和 ?? 誰尊重了這個 0?

運算子優先順序

一個運算式裡有好幾個運算子時,依優先順序計算(同一級通常由左到右)。由高到低大致是:

  1. 括號 ( )
  2. 一元運算子:!、typeof、++、--、正負號
  3. 次方 **(由右到左:2 ** 3 ** 2 是 2 ** 9)
  4. 乘、除、餘數 * / %
  5. 加、減 + -
  6. 比較 < > <= >=,再來是相等 === !== == !=
  7. &&,再來是 || 和 ??
  8. 條件運算子 ? :
  9. 指定 = += 等

簡單記法:算術 > 比較 > 邏輯 > 條件 > 指定。&& 比 || 優先,所以 true || false && false 先算 false && false。 ?? 不能直接和 &&、|| 混寫(例如 a || b ?? c 是語法錯誤),要加括號。 記不得的時候就加括號,程式也比較好讀。

位元運算子(&、|、^、~、<<、>>、>>>)把數字當成 32 位元的二進位來運算,例如 5 & 1 是 0101 & 0001,得到 1。 一般網頁程式很少用到,看到時知道它們是對位元運算即可。

優先順序:誰先算

每一行都先自己算一次再按下一步。第 9 行是投影片 Lab03 的題目;第 10 行看 && 比 || 優先;第 11 行的次方由右往左算。

想一想:邏輯運算子與優先順序

1.

下面的程式會印出什麼?

console.log(0 || 'A', 0 ?? 'A');
2.

下面的程式會印出什麼?

console.log('1' && 'str', 0 && 'str');
3.

下面的程式會印出什麼?

const user = null;
console.log(user?.name ?? '訪客');
4.

下面的程式會印出什麼?

console.log(1 + 2 * 3 ** 2);
第 1 次作答

實作:預設值與條件運算子

完成三個 TODO:沒有暱稱時顯示「同學」、0 分要保留為 0、用三元運算子判斷及格。完成後應該依序印出 同學、0、不及格。

你的輸出
預期輸出

重點精華回顧

  • 運算式會算出一個值;運算子依運算元數量分成一元、二元、三元。
  • 算術運算子 + - * / % **;+ 遇到字串就變成連接,其他算術運算子會把字串轉成數字。x++ 先取值再加,++x 先加再取值。
  • 比較的結果是布林值;== 會先轉換型別,一律用 ===、!==。字串比較是逐字的字典順序。
  • &&、|| 會短路求值,回傳的是其中一個運算元;falsy 只有 false、0、''、null、undefined、NaN(以及 -0、0n)。
  • ?? 只在 null、undefined 時使用預設值,?. 遇到 null、undefined 不會出錯;條件 ? 值1 : 值2 做二選一。
  • 優先順序大致是 算術 > 比較 > 邏輯 > 條件 > 指定;不確定時加括號。
這一課完成了!
Next lesson:字串
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。