---
title: 'JS 核心 6 - 運算子、優先性及相依性'
tags: JS 核心, Javascript, 運算子、型別與文法
description: 2021/02/03
---
JS 核心 -- 運算子、優先性及相依性
===
## 運算子
#### <span class="red">運算子 : 一定會回傳一個結果。</span>
把右邊的參數回傳至左邊來,並回傳一個結果。

### 一元運算子 (大部分為單字)
* <span class="green">**delete 可以刪除特定的物件屬性。**</span>

* <span class="green">**typeof 可以查詢一個特定值的型別,會回傳一個運算元的型別。**</span>

### 二元運算子
**加號 (+)** : 由左而右」且「先乘除後加減」的模式來運算。
特殊數字 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>