# 基本運算
# 數字
# 整數的基本運算
> 8 + 2 | |
10 | |
> 8 - 2 | |
6 | |
> 8 * 2 | |
16 | |
> 8 / 2 | |
4 |
# 符點數的基本運算
> 0.1 + 0.1 +0.1 | |
0.30000000000000004 | |
> 1.0 - 0.8 | |
0.19999999999999996 | |
> 0.1 * 3 | |
0.30000000000000004 | |
> 0.1 + 0.1 + 0.1 === 0.3 | |
false |
數字都是由 IEEE754 標準 64 位元浮點數,這個標準不是用小數點,而是分數 + 指數表示
例如: 0.5 = 1/2,0.875 = 1/2+1/4+1/8
像 0.1 = 1/16 + 1/32 + 1/256 + 1/512
... 沒有止境,因此造成浮點數誤差
需要靠到第三方程式庫來解決這問題
# 特殊運算
ES7 新增了指數運算子 **
,進行指數運算
> 3 ** 2 | |
9 | |
> 2 ** 5 | |
32 | |
> 9 ** 0.5 | |
3 | |
> |
a % b
可以取得 a 除以 b 的餘數
> 3 % 2 | |
1 | |
> 725 % 360 | |
5 |
在進行 /
運算時,如果除以 0
,會產生無限值。
> 1 / 0 | |
Infinity | |
> Infinity === Number.POSITIVE_INFINITY | |
true | |
> Infinity === Number.NEGATIVE_INFINITY | |
true |
# 字串
字串的加法運算,可以使兩個不同的字串 串接 在一起。
> let text1 = 'Zrn ' | |
undefined | |
> let text2 = 'Ye' | |
undefined | |
> text1 + text2 | |
'Zrn Ye' |
Javascript 為極度偏向弱型別的語言,也就是說, 數字 + 字串
,數字會被強轉為字串,在進行串接。
> 'Zrn Ye' + 1 | |
'Zrn Ye1' |
在 JS 世界裡,型態轉換太容易發生,有些轉換真的十分奇怪,此時建議就不要依賴這種轉換。
> '10' - '5' | |
5 | |
> '10' * '5' | |
50 | |
> '10' / '5' | |
2 |
若要以字串作為數字推薦使用 Number
函式轉換為數字:
> Number('10') - Number('5') | |
5 | |
> Number('10') * Number('5') | |
50 | |
> Number('10') / Number('5') | |
2 |
極度建議不要將算術運算子用在除數字會字串以外的地方。
> [] + []; | |
'' | |
> [] + {}; | |
'[object Object]' | |
> {} + []; | |
0 | |
> {} + {}; | |
NaN |
# 比較運算
字串的比較,會依照 Unicode
碼點 順序比較,因此 'AB'>'AC'
的回傳值為 true
,反之則為 false
# !==
與 ===
比較相等時建議使用 ===
及 !==
判斷,不建議使用 !=
或 ==
,因為他們的比較過於鬆散。
> '' == 0 | |
true | |
> null == undefined | |
true | |
> 1 == true | |
true |
相對的,使用 ===
或 !==
時,會採用嚴格比較規則,就連型態都要一致才行。
如果是在操作物件, =
將名稱參考某個物件,而 ===
是用來比較兩個名稱是否參考同一件物件。
> let x = new Number(10) | |
undefined | |
> let y = new Number(10) | |
undefined | |
> let z = x | |
undefined | |
> x === y | |
false | |
> x === z | |
true |
# NaN
當運算無法產生數值時,就會產生 NaN
。例如: 0 / 0
:
> 0 / 0 | |
NaN | |
> typeof NaN | |
'number' | |
> NaN === false | |
false | |
> NaN === Number.NaN | |
false |
NaN
是一種特殊值,他不等於任何的值,所以在做嚴格比對時,不會等於任何值。
# 邏輯運算子
符號 | 功能 | 範例 | 說明 |
---|---|---|---|
&& | 邏輯 AND | a>2&&a<9 | 若 2<a<9 則結果為真 |
|| | 邏輯 OR | a9 | 若 a9 則為真 |
! | 邏輯 NOT | !(a==1) | 若 a≠1 則結果為真 |
# 表達式的值
邏輯值: true
、 false
- 運算
<條件式1> && <條件式2>
,兩個都為 true ➡️ true
條件式 1 | 條件式 2 | 結果 |
---|---|---|
false | false | false |
false | true | false |
true | false | false |
true | true | true |
- 運算
<條件式1> || <條件式2>
,任一個為 true ➡️ true
條件式 1 | 條件式 2 | 結果 |
---|---|---|
false | false | false |
false | true | true |
> let number = 75 | |
undefined | |
> number > 70 && number < 80 | |
true | |
> number > 80 || number < 75 | |
false | |
> !(number > 80 || number < 75) | |
true |
在 JS 世界裡,除了 0
、 NaN
、 ''
、 null
、 undefined
是 false
以外,其餘全部都是 true,那五個東西被稱作 Falsy Family。
#位元運算子
二元運算子 功能 邏輯
& 按位 “與” and
| 按位 “或” or
^ 按位 “異或” xor
~ 按位 “變反” not
<< 左移
右移
> 0b1010001 & 0b010111 | |
1 | |
> let number1 = 0b0011 | |
undefined | |
> number1 | |
3 | |
> ~number1 | |
-4 |
number1
原為 0011
經補數運算後變成 1100
因此變為 -4
位元運算也有左移與右移兩種運算模式
let n = 1; | |
console.log*('2的0次方: ',n); | |
console.log*('2的1次方: ',n<<1); | |
console.log*('2的2次方: ',n<<2); | |
console.log*('2的3次方: ',n<<3); |
輸出結果為:
2的0次方: 1
2的1次方: 2
2的2次方: 4
2的3次方: 8
實際的運算狀況:
000001 -> 1
000010 -> 2
000100 -> 4
001000 -> 8
# 條件、指定 與 遞增 / 減
# 條件運算子
<條件式> ? <表達式1> : <表達式2> |
- 當
<條件式>
為真,則運行<表達式 1>
- 當
<條件式>
為假,則運行<表達式 2>
let x = 10, y = 20; | |
console.log( ( x < y ) ? 'x < y': 'x >= y'); // 輸出 x < y |
# 指定運算子
二元運算子 | 功能 | 範例 | 說明 |
---|---|---|---|
= | 簡單指定 | x = y | 令 x = y |
+= | 加法指定 | x += y | 令 x = x + y |
-= | 減法指定 | x -= y | 令 x = x - y |
*= | 乘法指定 | x *= y | 令 x = x * y |
/= | 除法指定 | x /= y | 令 x = x /y |
**= | 乘法指定 | x **= y | 令 x = x ** y |
%= | 餘數指定 | x %= y | 令 x = x % y |
&= | 複合與 | x &= y | 令 x = x & y |
|= | 複合或 | x |= y | 令 x = x | y |
^= | 複合異或 | x ^= y | 令 x = x ^ y |
<<= | 複合左移 | x <<=k | 令 x = x << k |
>>= | 複合右移 | x >>=k | 令 x = x >>k |
# 遞增遞減運算子
前置 ++
: ++i
,後置 ++
: i++
前置 --
: --i
,後置 --
: i--
- 為一元運算子
- 無論是前置或是後置, ++ 皆會使變數自身 + 1, -- 皆會使變數自身 - 1
let n = 5,m = 10; | |
let n++; // 相當於 n = n + 1; | |
let m--; // 相當於 m = m - 1; | |
console.log(n); // 結果為 6 | |
console.log(m); // 結果為 9 |
- 作為表達式的話,
前置運算子會先將變數 +1/-1 後,再去做運算
後置運算子會先運算變數,之後再 +1/-1
let n = 5,m = 10; | |
let a,b,c,d | |
a = n++; // a = 5 ,n = 6 | |
b = m--; // b = 10 ,m = 9 | |
n = 5,m = 10; | |
a = ++n; // a = 6 , n = 6 | |
b = --m; // b = 9 , m = 9 |