--- title: 'JS 核心 9 - 邏輯運算子及函式預設值' tags: JS 核心, Javascript, 邏輯運算子及函式預設值 description: 2021/02/04 --- JS 核心 -- 邏輯運算子及函式預設值 === ## 邏輯運算子 ✏ <span class="red">**其中 && 和 || 左右兩邊是表達式,會回傳一個值 (只要判斷 expr1 第一個值就好)**</span>  ### && (邏輯AND) : 驗證兩個值是否為真值 若 expr1 為 false,就返回 expr1 ``` console.log( undefined && 1 ); // undefined (expr1 為假值,回傳第一個值) console.log( 0 && 1 ); // 0 (expr1 為假值,回傳第一個值) ``` 若 expr1 為 true,就返回 expr2 (不管 expr2 的值為何) ``` console.log( 1 && 0 ); // 0 (expr2 為假值,回傳第二個值) console.log( 1 && 2 ); // 2 (expr1 為直值,回傳第二個值) ``` ### || (邏輯OR) : 驗證兩個值是否(其中一個)為真值 若 expr1 為 true,就回傳 expr1 若 expr1 為 false,就回傳 expr2 ``` console.log(1 || 0); // 1 (expr1 為直值,回傳第一個值) console.log(0 || 1); // 1 (expr2 為直值,回傳第二個值) console.log(undefined || 1); // 1 (expr2 為直值,回傳第二個值) ``` ### ! (否定) : 如果是true,就返回false ``` console.log( !0 ); // true (0是假值) console.log( !1 ); // false console.log( ![] ); // false (空陣列是真值) ``` 📝 **範例 :** (驗證是否為真值的方法) ``` var originCash = 500; function updateEasyCard(cash){ // 更新金額的函式,會傳入參數cash var money = cash + originCash; console.log('我有' + money + '元'); } updateEasyCard(100); // 我有 600 元 ``` 若把 updateEasyCard ( ) ; 裡的參數拿掉,觀察其變化 可參考[隱含轉型筆記](https://hackmd.io/@peggyted0129/Sk9hJBOlu) ``` var originCash = 500; function updateEasyCard(cash){ console.log(cash); // undefined (沒有把值傳入cash,回傳undefined) console.log( Number(undefined) ); // NaN var money = cash + originCash; console.log('我有' + money + '元'); } updateEasyCard(); // 我有 NaN 元 ( undefined 和 數字相加,會出現 NaN 的值) ``` ## 函式預設值 #### 承上範例程式碼,加入邏輯運算子 (驗證是否為真值的方法) 1. 若 cash 為真值,就直接回傳;否則就回傳100元 2. 目前 cash 沒有傳任何的值進來,所以為 undefined 3. cash 為 undefined 就直接跳過 cash ,回傳 100 ``` var originCash = 500; function updateEasyCard(cash){ cash = cash || 100; var money = cash + originCash; console.log('我有' + money + '元'); } updateEasyCard(); // 我有 600 元 ``` 承以上範例,若 updateEasyCard(0); ( cash 傳 0 進去),0 會被判定為假值,還是會套用 100 這個數值。這情境下就無法使用預設值的方法。 <span class="red">**預設值為 0 的解決方法: 使用三元運算子**</span> ``` var originCash = 500; function updateEasyCard(cash) { cash = parseInt(cash); console.log(cash); // 當 cash 是數值或為 0 時,使用 cash 的數值 // 如果 cash 是 NaN 時,則直接套用 500 cash = (cash || cash === 0) ? cash: 500; var money = cash + originCash; console.log('我有 ' + money + ' 元'); } updateEasyCard(0); // 我有 500 元 ``` ## 總結 **✏ 範例 :** 物件與非物件寬鬆相等比對時,會使用包裹物件做轉換 ``` var a = 1; var b = new Number(1); // 使用建構式的方式建立數字 1 console.log(b); // Number{1} console.log(Number(b)); // 1 (得到數字 1) console.log(a == b); // true console.log(a === b); // false ( a 型別是數字,b 型別是物件 ) ``` **✏ 範例 :** || (邏輯OR) - 左右兩邊放的是表達式,會回傳表達式的內容 (而非回傳 true 或 false) ``` var a = 1; var b = 0; console.log(1 || 0); // 1 ``` **✏ 範例 :** 這裡的 &&(邏輯and) 屬於二元運算子,一次只能做左右兩邊的比對(無法一次比對整行) 有執行順序的:由左至右。 可參考 [MDN 優先順序](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)  先執行 a && b (得到 2),執行完的結果再比對 2 && c (得到 0) < && 當第一個為false時,直接回傳。 否則回傳第二個值 > ```typescript= var a = 1; var b = 2; var c = 0; console.log(a && b && c); // 0 ``` 以下範例透過[MDN 優先順序](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)得知會先執行 && 而不是 ||  先執行 c && c (得到 0) -> console.log(c || 0 || a); 再執行 c || 0 (得到 0) -> console.log(0 || 0 || a); || 當第一個為 false 時,回傳第二個值 -> 最後得到 a 的值,答案為 1 ```typescript=5 console.log(c || c && c || a); // 1 ``` 由 "MDN 優先順序" 得知 && 會先執行 && 當第一個為false時,直接回傳。 否則回傳第二個值 先執行 a && b (得到 2),由於 a 是真值,回傳 b 的值 -> console.log(b || c && a); 再執行 c && a (得到 0),由於 c 是假值,回傳 c 的值 -> console.log(b || c); 最後執行 b || c (得到 b),由於 || 當第一個為 true 時,回傳第一個值 -> 最後得到 b 的值 ```typescript=6 console.log(a && b || c && a); // 2 ``` **✏ 範例 :** 優先序的概念 - 運算子彼此之間的執行順序 由 "MDN 優先順序" 得知 = 的優先序是 9 , + 的優先序是 13 先執行 1 + 1 ,得到 2 -> var a = 2 === 1; (得到 false) ``` var a = 1 + 1 === 1; console.log(a); // false ``` **✏ 範例 :** 相依性的概念 - 指的是運算方向 由 "MDN 優先順序" 得知,比對的運算子是由左至右 這裡的 < 屬於二元運算子,一次只能做左右兩邊的比對(無法一次比對整行) 先執行比對 1000 < 10000 (得到 true) -> console.log(true < 10); 再執行比對 true < 10 (得到 true),true 被轉型為數字 1,所以答案為 true ``` console.log(1000 < 10000 < 10); // true ``` **✏ 範例 :** c 是三元運算子,其中的 (a > b) 是判斷式,字串 a 會自動轉型為數字和 b 做比對,得到 false,所以 c = sum(a, b) sum(a, b) 會把 a, b的值傳進來,得到字串 '12' ``` var a = '1'; // 字串型別 var b = 2; // 數字型別 var c = (a > b) ? a * b : sum(a, b); // ? 前面是判斷式,: 前後是表達式 function sum(a, b) { return a + b; // 字串 '1' + 數字 2,得到字串 '12' } console.log(c); // 字串 '12' ``` **✏ 範例** ``` var d = null; console.log(typeof d); // object var e = NaN; console.log(typeof e); // number ``` **✏ 範例** ``` var a = 10; console.log(++a * a); // 121 console.log(a); // 11 console.log(++a); // 11 a = 10; console.log(--a * a); // 81 ``` ## :memo: 學習回顧 :::info * && 和 || 左右兩邊是表達式,會回傳一個值 (只要判斷 expr1 第一個值就好) * && (邏輯AND) : 若 expr1 為 false,就返回 expr1; 反之,返回 expr2 * || (邏輯OR) : 若 expr1 為 true,就回傳 expr1 ; 反之,返回 expr2 * ! (否定) : 如果是true,就返回false * 二元運算子,一次只能做左右兩邊的比對(無法一次比對整行) * (等號 =) 的相依性(運算方向) : 由右至左 ::: <style> .red { color: red; } .green { color: green; } </style>
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up