0%

JavaScript 運算子

運算子

舉凡加減乘除都是運算子,等號也是運算子之一。
(詳細可參考 MDN-運算子)。

  • 運算子均為表達式,一定會回傳值
  • 一元運算子
    • let a = 1
  • 二元運算子
    • let b = 1 + 2
  • 三元運算子
    1
    2
    let c = true
    console.log(c ? 'Y' : 'N')
  • 物件增加屬性的方法 . ,也是一個運算子,.[] 在運算子中為最優先

優先性、相依性

  • 運算子有其優先順序
    • 乘除的優先序大於加減的優先序
  • 相依性則決定了運算方向
    • 絕大多數的運算子都是從左至右
    • 等號賦值為從右至左
  • 經典題目 : 6/2(2+1) = ?

比較運算子

1
2
3
4
5
6
7
8
// 從左至右,逐一比較
console.log(3 > 2 > 1)
// 3 > 2 為 true
// true > 1 為 false

console.log(1 > 2 > 3)
// 1 < 2 為 false
// false > 3 為 false

賦值運算子

1
2
3
4
5
// 從右至左,逐一賦值
let a = 1
let b = a
a = b = 3
console.log(a)

Member Access .

這縮寫為點的運算子,可以尋找/賦予物件的屬性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 物件屬性賦值
let obj = {}
let b ;

// Object.defineProperty 可以定義物件中某個屬性的內建屬性
Object.defineProperty(obj, 'a', {
value: 3,
writable: false
})
b = obj.a
obj.c = b = 5
console.log(obj.a, b, obj.c)
// 3 5 5
// obj.a 無法被修改
// b 再度被"賦予值"
// 依據運算子的優先順序,物件的成員也就是屬性,它的優先順序大於等號
// 物件 obj,會先建立了 c這個屬性,之後才被等號賦予值

物件傳參考賦予值

運算子與物件傳參考綜合使用。

  1. 物件 e會先建立屬性名稱 x
  2. 接著依照等號運作從右至左賦值
  3. 物件 e另開了一個位址
  4. 原先的物件 e的確有新增屬性名稱 x,且被賦予物件
  5. 原先的物件 e依然被 f參考
1
2
3
4
5
6
7
8
9
10
11
let e = {n:1}
let f = e
e.x = e = {n:2}

console.log(e.x)
console.log(e.q)
console.log(f.x)
// undefined
// undefined 物件已存在,可以直接增加屬性名稱
// 呼叫 e.q時,不會是 'q is not defined',所以呼叫 e.x也是一樣的,只不過物件 e已新開參考位址
// {x:2}

寬鬆與嚴謹模式

一個等號為賦值,兩個等號為寬鬆判斷,三個等號為嚴謹判斷。

  • 寬鬆判斷
    • 當兩者型別不同時,JS會嘗試轉換型別。
  • 嚴謹判斷
    • 當兩者型別不同時,JS不會轉換型別。
1
2
3
4
5
console.log(1 == 1)    // true
console.log(1 == '1') // true
console.log(1 === '1') // false
console.log(1 != '1') // false
console.log(1 !== '1') // true

隱藏型別 / 自動轉型

在判斷是否相等時,根據模式 JS會將型別自動轉型(踩地雷~砰!)。

寬鬆判斷時

  • 字串與數字
  • 布林與數字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 字串與數字
console.log('1' == 1 ? 'Y' : 'N') // 'Y'

// 布林與數字
console.log(true == 1 ? 'Y' : 'N') // 'Y'
console.log(true == 0 ? 'Y' : 'N') // 'N'
console.log(false == 0 ? 'Y' : 'N') // 'Y'
// JS會嘗試將布林值轉成數字
// Number(true),1

// 字串與數字 ???
console.log('false' == 0 ? 'Y' : 'N') // 'N'
// JS會嘗試將字串轉成數字
// Number('false'),NaN

算數運算子

1
2
3
4
console.log('1' + 1) // 字串
console.log('1' - 1) // 數字
console.log('1' * 2) // 數字
console.log('1' / 2) // 數字

包裹物件

它們的型別為物件,JS在寬鬆相等判斷時會利用這些來轉型,像是這些 :

  • Number()
  • String()
  • Boolean()

Truthy & Falthy

這邊指得是在某個函式中的參數,若放入以下其中一種單一值,其值被判定後的結果,與相等判斷、邏輯判斷概念不太一樣。

  • 參數其值為單一數字、字串、物件、陣列、建構函式、Infinity、-Infinity以及 true,均為真值
  • 參數其值為 false0""nullundefinedNaN 均為假值
  • 也就是說,除了假值之外,其餘均為真值。
1
2
3
4
5
6
7
let x = 1 // 可自由替換
if (x) {
console.log('被判定為 true,故為真值')
} else {
console.log('被判定為 false,故為假值')
}
console.log(Boolean(x))

邏輯運算子

共有三種,優先順序為 ! 大於 && 大於 ||,相依性為由左至右,而且在邏輯判斷時,型別不會自動轉換。

AND &&

  • 當前者可被轉型成 false時,會回傳前者結果
  • 若否,回傳後者結果
  • 也因此若兩者皆為布林值,根據規則剛好與”真值表”相同

OR ||

  • 當前者可被轉型成 true,會回傳前者結果
  • 若否,回傳後者結果
  • 也因此若兩者皆為布林值,根據規則剛好與”真值表”相同

NOT !

  • 會將布林值反轉
  • 可以將 Truthy & Falthy的結果反轉
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// AND `&&`
console.log( 0 && 1) // 0
console.log('0' && 1) // 1
console.log( false && 1<2) // false
console.log( '' && 1) // ''
console.log( true && 3>2) // true
console.log( 3>2 && false) // false

// OR `||`
console.log(0 || 1) // 1
console.log('0' || 1) // '0'
console.log( false || 1<2) // true
console.log( '' || null) // null
console.log( true || 3>2) // true
console.log( false || 3>2 ) // true

// NOT `!`
console.log( !1 || 2) // 2
console.log( !null || 2) // true
console.log( !null && !'') // true
console.log( !null && []) // []

綜合練習 - 函式預設值

請修改以下函式,當函式未給值時,不讓它成為假值。

1
2
3
4
5
6
7
8
9
let x = 500
const fn = (y) => {
x += y
console.log(`本次儲存 ${y} 元!,您共有 ${x} 元。`)
}
fn()
// 本次儲存 undefined 元!,您共有 NaN 元。"
// undefined,其為函式參數預設值
// 數值與 undefined相加,會變成 NaN

修改函式後

1
2
3
4
5
6
7
8
let x = 500
const fn = (y) => {
y = (y || y === 0) ? y: 500;
x += y
console.log(`本次儲存 ${y} 元!,您共有 ${x} 元。`)
}
fn()
// "本次儲存 500 元!,您共有 1000 元。"

參考來源

  1. 六角學院 JS核心篇 - 運算子章節
  2. MDN - Object.defineProperty()
  3. MDN - Truthy(真值)
  4. MDN - 預設參數( Default parameters )
  5. SimonAllen - Day17 傳值by value與傳址by reference
  6. Yi-Ning - JavaScript 核心篇 學習筆記: Chap.33 — 未定義的物件屬性預設值
  7. Jimmy - Day 13 物件與點
  8. Kuro Hsu - 重新認識 JavaScript: Day 08 Boolean 的真假判斷