--- title: 'JS 核心 6 - 運算子、優先性及相依性' tags: JS 核心, Javascript, 運算子、型別與文法 description: 2021/02/03 --- JS 核心 -- 運算子、優先性及相依性 === ## 運算子 #### <span class="red">運算子 : 一定會回傳一個結果。</span> 把右邊的參數回傳至左邊來,並回傳一個結果。 ![](https://i.imgur.com/zI4EIRR.png) ### 一元運算子 (大部分為單字) * <span class="green">**delete 可以刪除特定的物件屬性。**</span> ![](https://i.imgur.com/PVLnwm1.png) * <span class="green">**typeof 可以查詢一個特定值的型別,會回傳一個運算元的型別。**</span> ![](https://i.imgur.com/xkjY2IK.png) ### 二元運算子 **加號 (+)** : 由左而右」且「先乘除後加減」的模式來運算。 特殊數字 NaN - 只要有其中一個是 NaN,那麼結果就必定是 NaN。 ``` 10 + NaN // NaN Infinity + NaN // NaN -Infinity + NaN // NaN ``` 當加號 + 兩側的其中一方是字串的情況下,**加號 + 會將兩者都視為「字串」連接在一起**。 ``` 10 + 'abc' // "10abc" true + 'abc' // "trueabc" 100 + {} // "100[object Object]" // 當數字與 undefined 相加時,undefined 會被嘗試轉成數字,也就是 NaN 123 + undefined // NaN "abc" + undefined // "abcundefined" // 當數字與 null 相加時,null 會被嘗試轉成數字,也就是 0 123 + null // 123 "123" + null // "123null" ``` ``` var num1 = 10; var num2 = 100; var str = "10 加 100 的數字會是" + num1 + num2; console.log(str); // "10 加 100 的數字會是10100" ``` **減號 (-)** : 若其中一方屬於基本型別且不是數字的情況,那麼 JavaScript **會在先在背後透過 Number() 嘗試將數值轉為「數字」,再進行運算。** ``` 100 - "50" // 50 100 - "abc" // NaN // false 經過 Number() 轉型成數字後,會變成 0 100 - false // 100 // true 經過 Number() 轉型成數字後,會變成 1 100 - true // 99 100 - undefined // NaN 100 - null // 100 ``` **乘號 (*)** : 如果有其中一個不是數字的話,那麼 JavaScript 就**會先在背後以 Nubmer() 作轉換後再進行計算。** ``` 100 * "10" // 1000 100 * abc // NaN 100 * true // 100 100 * false // 0 100 * {} // NaN ``` ### 三元運算子 [(條件運算子)](https://developer.mozilla.org/zh-tw/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) * 在一個條件後面會跟著一個問號 (?),如果條件是 truthy,在冒號(:)前的表達式會被執行,如果條件是 falsy,在冒號後面的表達式會被執行。 * 這個運算子常常被用來當作 if 的簡潔寫法。 * 三元運算子也會回傳一個結果,依據判斷式決定要回傳哪一個表達式的結果。 ``` function getFee(isMember) { return (isMember ? '$2.00' : '$10.00'); } console.log(getFee(true)); // "$2.00" console.log(getFee(false)); // "$10.00" ``` ``` var bmi = 15; var result = (bmi < 20) ? '偏瘦' : '肉肉的' ; console.log(result); // 偏瘦 ``` ## 優先性及相依性 :bulb: [參考 MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table) * **優先性 Precedence:** 運算子彼此之間的執行順序。例如:乘除優先於加減,因此先執行乘除後執行加減。 * **相依性 Associativity:** 指的是運算方向。例如:加號的相依性是由左至右,但等號是由右至左。當兩個運算子的優先性相同時(例如加號和減號),就會依據相依性的方向來執行。 **範例** ``` console.log( 1 < 2 < 3 ); // true console.log( 3 > 2 > 1 ); // false ``` 執行順序會先 3 > 2 先產生一個結果,然後再去比對是否 > 1。 ``` console.log(3 > 2); // true console.log(true > 1); // false console.log(1 > 1); // false (true會因為型別的轉換變成1) ``` **範例 :** <span class="red">等號的賦值是由右至左。</span> 執行順序 : <span class="red"> a 是取**3 賦予至 b**的回傳結果,並不是直接取 b 的結果。</span>在 console 輸入b = 3,會回傳值 3 ,所以這個 3 就藉由等號再次賦予到 a 上。 ``` var a = 1; var b = 2; a = b = 3; console.log(a, b); // 3, 3 ``` **範例 :** 表達式概念 1. 先宣告變數 b 為一物件 2. 在此 b 物件下又重新定義屬性 a 3. 屬性 a 的值為 2 (有設條件為 "不可寫入") ```typescript= var b = {}; // 宣告變數 b 為一物件 Object.defineProperty(b, 'a', { value: 2, writable: false }); b.a = 3; // 值永遠是 2 (有設立條件 "不可寫入") console.log(b.a); // 值永遠是 2 (不會被複寫) ``` 此段程式碼 b.a 是表達式 (會回傳一個結果為 1) a 接收了 b.a 表達式的回傳結果,所以 a 為 1 ```typescript=8 var a = 3; a = b.a =1; console.log( a , b.a ); // 答案是(1,2) ``` **範例 :** 表達式概念 ``` var b = {}; Object.defineProperty(b, 'a', { value: 2, writable: false }); Object.defineProperty(b, 'b', { value: 3, writable: false }); console.log(b); // {a: 2, b: 3} , b 物件裡的 2 個屬性,都無法被再次寫入 ``` b 物件裡的 2 個屬性 (b.b 和 b.a),都無法被再次寫入。 當 b.a = 1 時 (回傳結果為1),1 再賦予到 b.b 上。 當 b.b = 1 時 (回傳結果為1),1 再賦予到 a 上。 ``` var a = 3; a = b.b = b.a = 1; // 每個片段均為表達式,都會回傳結果 console.log(a); // 1 ``` ## :memo: 學習回顧 :::info * 運算子 : 一定會回傳一個結果。 * 當加號 + 兩側的其中一方是字串的情況下,<span class="red">加號 + 會將兩者都視為「字串」連接在一起。</span> * <span class="red">減號、乘號、除號、取餘數 :</span> 若其中一方屬於基本型別且不是數字的情況,那麼 JavaScript 會在先在背後透過 Number() 嘗試將數值<span class="red">轉為「數字」</span>,再進行運算。 * 優先性 Precedence: 運算子彼此之間的執行順序。 * 相依性 Associativity: 指的是運算方向。 * 「運算子」 當優先性相同時,則依相依性規則,由左至右執行。 * 等號 ( 它是表達式): 賦值由右至左,但同時也必須回傳值。 * 所有的表達式都會回傳值,但如果沒有去接收它時,他就會立即被釋放,不會儲存,就只是一個過程。 ::: ## :+1: 相關參考文件 :::info [運算式與運算子](https://ithelp.ithome.com.tw/articles/10191180) ::: <style> .red { color: red; } .green { color: green; } </style>