owned this note
owned this note
Published
Linked with GitHub
### 🔍小範例大學問👊
# [<font color="#f00">JavaScript</font>] 何謂強制轉型、以及如何作到轉換型別?
---
## 1. 強制轉型的種類:
* 「明確的」強制轉型(explicit coercion):
程式碼中刻意寫出來的型別轉換。
* 「隱含的」強制轉型(implicit coercion):
程式碼中沒有明確指出要轉換型別卻轉型了。
## 2. 「明確的」強制轉型(explicit coercion):
#### 🔄強制轉型成字串 String()
```javascript=
let a = 1;
let b = String(a);
console.log(typeof a); // number
console.log(typeof b); // string
```
```javascript=
let c = null;
let d = String(c);
console.log(typeof d, d); // string null
let e = undefined;
let f = String(e);
console.log(typeof f, f); // string undefined
let g = true;
let h = String(g);
console.log(typeof h, h); // string true
let i = [1, 2, 3];
let j = String(i);
console.log(typeof j, j); // string "1,2,3"
let n = {
myName: "Peter",
age: 18
};
let m = String(n);
console.log(typeof m, m); // string [object Object]
```
💬說明:物件轉型字串時,不管物件內容為何,強制轉型後都會形成 [object Object] 。
#### 🔄強制轉型成數字 number()
```javascript=
let a = '1';
let b = Number(a);
console.log(typeof b, b); // number 1
```
```javascript=
let a = '我是誰';
let b = Number(a);
console.log(typeof b, b); // number NaN
let c = [1, 2, 3];
let d = Number(c);
console.log(typeof d, d); // number NaN
let e = {
age : 18,
myName :'Peter'
};
let f = Number(e);
console.log(typeof f, f); // number NaN
```
💬說明:如果轉型字串非數字時,強制轉型後會形成 NaN 。
```javascript=
let a = null;
let b = Number(a);
console.log(typeof b, b); // number 0
let c = undefined;
let d = Number(c);
console.log(typeof d, d); // number NaN
let e = true;
let f = Number(e);
console.log(typeof f, f); // number 1
```
💬說明: true 的值為 1 ; false 的值為 0 。
#### 🔄強制轉型成布林值 number()
```javascript=
let a = '';
let b = Boolean(a);
console.log(typeof b, b); // boolean false
let c = NaN;
let d = Boolean(c);
console.log(typeof d, d); // boolean false
let e = 0;
let f =Boolean(e);
console.log(typeof f, f); // boolean false
let g = null;
let h =Boolean(g);
console.log(typeof h, h); // boolean false
let i = undefined;
let j =Boolean(i);
console.log(typeof j, j); // boolean false
let m = false;
let n =Boolean(m);
console.log(typeof n, n); // boolean false
```
💬說明:除了上述六種情況都會強制轉型為 boolean 的 false 之外,都會轉型成 boolean 的 true。
| ( 六種 | 強制轉型 | false ) | | | |
|:-----:|:--------:|:-----:|:----:|:---:|:---------:|
| false | 空字串 | 0 | null | NaN | undefined |
## 3. 「隱含的」強制轉型(implicit coercion):
#### 🔄強制轉型成字串 string ( +加法 )
```javascript=
const a = '2';
const b = 3;
const c = true;
const d = null;
const e = undefined;
const f = NaN;
const g = [4, 5];
const h = {
A:1,
B:2
}
console.log(a + b); // 23
console.log(a + c); // 2true
console.log(a + d); // 2null
console.log(a + e); // 2undefined
console.log(a + f); // 2NaN
console.log(a + g); // 24,5
console.log(a + h); // 2[object Object]
```
💬說明:字串跟所有型別做加法時,皆會強制轉型為字串。
```javascript=
console.log(typeof (b + c)); // number
console.log(typeof (b + d)); // number
console.log(typeof (b + e)); // number
console.log(typeof (b + f)); // number
console.log(typeof (b + g)); // string
console.log(typeof (b + h)); // string
```
💬說明:除了數字型別之外的加法,皆會強制轉型為字串。
| ( + 法 | 視為 | 數字型別 ) | | |
|:------:|:-------:|:----------:|:----:|:---------:|
| number | boolean | NaN | null | undefined |
#### 🔄強制轉型成數字 number ( -減 *乘 /除法 )
```javascript=
console.log(typeof (b - a)); // number
console.log(typeof (b * a)); // number
console.log(typeof (b / c)); // number
console.log(typeof (b - c)); // number
console.log(typeof (b * d)); // number
console.log(typeof (b / d)); // number
console.log(typeof (b * e)); // number
console.log(typeof (b / e)); // number
console.log(typeof (b * f)); // number
console.log(typeof (b / f)); // number
```
💬說明:毫無懸念,全數為數字型別(但不是所有都是強制轉型,可參考上面的那張表格)。
* <font color="#f00">來看一下陣列和物件做減、乘、除法,會如何?</font>
```javascript=
console.log(typeof (g - h), g - h); // number NaN
console.log(typeof (g * h), g * h); // number NaN
console.log(typeof (g / h), g / h); // number NaN
```
💬說明:沒想到,還是強制轉型為數字型別(竟然不會報錯!)。
#### 🔄強制轉型成布林值 boolean
在什麼狀況下會隱含地將值強制轉為布林呢?直接看實例吧。
```javascript=
let a = 520;
let b = '森七七也是真的';
let c = undefined;
let d = null;
if (a) {
// true
console.log(`${a}是真的`); // 520是真的
}
while (c) {
// false
console.log('我想~不告訴你'); // 因為是false,所以不會出現
}
let tellMe = (c == d) ? b : a;
//true
console.log(tellMe); // 森七七也是真的
if (a || b) {
// true
console.log('你搞的我好亂啊'); // 你搞的我好亂啊
}
```
| ( 強制轉型布林 ) |
|:---------------------------------- |
| if => 條件判斷 |
| for => 的條件判斷 |
| while => 條件是否成立 |
| 三元運算式 => 值1 : 值2 的條件運算 |
| 邏輯運算子 => OR 、 AND |
## 4. Symbol 的強制轉型:
```javascript=
const a = Symbol('強制轉字串很可以');
String(a);
console.log(a);// "Symbol(強制轉字串很可以)"
const b = Symbol('轉字串來暗的不行喔');
b + ''; // TypeError: Cannot convert a Symbol value to a string(錯誤訊息)
```
💬說明:在轉為字串方面,將 symbol 明確的強制轉型是允許的,但隱含的強制轉型是被禁止的,並且會丟出錯誤訊息。
```javascript=
const c = Symbol(123);
Number(c); // TypeError: Cannot convert a Symbol value to a number(錯誤訊息)
const d = Symbol(456);
789 + d; // TypeError: Cannot convert a Symbol value to a number(錯誤訊息)
```
💬說明:在轉為數字方面,無論是明確或隱含都是禁止的,並且會丟出錯誤訊息。
```javascript=
const e = Symbol(true);
const f = Symbol(false);
Boolean(e); // true
Boolean(f); // true
console.log(e); // Symbol(true)
console.log(f); // Symbol(false)
const g = Symbol(true);
const h = Symbol(false);
if (g) {
console.log('g 是真的');
}// g 是真的
if (h) {
console.log('h 是真的');
}// h 是真的
```
💬說明:在轉為布林方面,無論是明確或隱含都是可以的,並且結果都是 true。
| Symbol | 明確強制轉型 | 隱含強制轉型 |
|:--------:|:------------:|:------------:|
| 轉成字串 | ✔️ | ❌ |
| 轉成數字 | ❌ | ❌ |
| 轉成布林 | ✔️ | ✔️ |
## 5. 有用的功能? OR 缺陷?:
當你對隱含的強制轉型停留在一知半解的階段時,就會覺得這個設計是極大的缺陷;但了解透徹之後,或許它就會變成了有用的功能,減少冗贅、反覆套用與避免過於細節調節的步驟。
| 隱含的強制轉型 | 數字 | 字串 | 布林 |
| -------------------------------------- |:----:|:----:|:----:|
| 運算類:加( + )法 | | ✔️ | |
| 運算類:減( - )乘( * )除( / )法 | ✔️ | | |
| if、for、while、三元運算式、邏輯運算子 | | | ✔️ |
💬說明:方便記憶的簡表,詳細內容還是需要爬一下文。
---
#### 參考文章
* [你懂 JavaScript 嗎?#8 強制轉型(Coercion)](https://cythilya.github.io/2018/10/15/coercion/)