###### tags: `學習` `強制轉型`
{%hackmd BJrTq20hE %}
# JavsScript的強制轉型與轉換型別(字串、數字、布林篇)
簡單的來說在JacaScript中的邏輯比較子不是嚴謹模式的時候,JacaScript會貼心 ~~(欠揍)~~ 的幫你轉換成同的的型別再進行比較。
例如
```javascript=
console.log('1'==1);//true
console.log(''==false);//true
console.log([]==false);//true
console.log('0'==0);//true
console.log('0'==false);//true
```
看到上面的範例是不是覺得JacaScript很貼心 ~~(欠揍)~~ 阿
## 轉型有分隱性(Implicit)與顯性(explicit)
~~什麼鬼?! 強制轉型就轉型,還分顯性、隱性,又不是在做豌豆雜交實驗。~~
1.顯性(explicit)就是使用語法直接轉型
例如
```javascript=
let a = '123';
console.log(Number(a) ,typeof Number(a))//123 number
let b = false;
console.log(String(b) ,typeof String(b))//false string
```
用語法把字串123轉型為數字與false布林轉成字串就叫做顯性(explicit)轉型
2.隱性(implicit)就是JS"貼心的"幫你轉型
例如
```javascript=
console.log("1"==false)//fales
console.log("1"==1)//ture
console.log(""==false)//ture
console.log("0"==false)//ture
console.log("" || false)//false
console.log("" && false)//""
```
只要不是自己主動使用語法轉型的都是隱性(implicit)轉型
"1"自動轉型成布林true,再與false做比較。
"1"自動轉型成number 1,再與1做比較。
""自動轉型成布林 false,再與false做比較。
"0"自動轉型成布林 false,再與false做比較。
"" 碰到邏輯運算子 自動轉型為false布林,再進行邏輯運算。
"" 碰到邏輯運算子 自動轉型為false布林,再進行邏輯運算。
**注意**
自動轉型只會發生在非嚴謹模式,簡單的來說只會再 == 兩個等號才會幫你自動轉型
## 字串的轉型
字串的隱性轉型(implicit)很簡單,只要遇到+與字串,就會自動轉型為字串了
例如
```javascript=
console.log('string'+'string',typeof ('string'+'string'))stringstrimg string
console.log(123+'string',typeof (123+'string'))//123string string
console.log(true+'string',typeof (true+'string'))//truestring string
console.log([]+'string',typeof([]+'string'))//string string
console.log({}+'string',typoof({}+'string'))//[object Object]string string
```
字串+字串 自動轉型為 字串
數字+字串 自動轉型為 字串
布林+字串 自動轉型為 字串
陣列+字串 自動轉型為 字串
物件+字串 自動轉型為 字串
那顯性(explicit)轉型呢?
直接看範例
```javascript=
console.log(String(123),typeof(String(123)))//123 string
console.log(String(null),typeof(String(null)))//null string
console.log(String(undefined),typeof(String(undefined)))//undefined string
console.log(String(true),typeof(String(true)))//true string
```
無一例外的通通被轉型成字串
## 布林的轉型
布林的自動轉型跟falsy(偽值)與truthy(真值)有關,只要會分辨falsy與truthy,那布林的隱性轉型也是很好判斷的。
下面的表為各型別資料在布林裡為真值或偽值
|型別|truthy|falsy|
|:--:|:----:|:----:|
|boolean|ture|false|
|Array|一律為truth即使為空字串|X|
|Object|一律為truth即使為空物件|X|
|string|""空字串|"0"非空字串(只有字串內有東西)|
|number|除了0與NaN以外的數字皆為truthy|+0 -0 0與NaN|
|undefined|X|一律為falsy|
|null|X|一律為falsy|
了解上面的表之後就來看一些布林的隱性(implicit)轉型範例吧
```javascript=
if(2){
console.log('我執行了')
}
else{console.log('我沒執行')}
//我執行了
console.log('' || 123)//123
console.log(!'' || 123)//true
```
來解析一下上面的程式碼
1.if判斷式內只能為true或是false,2兩者都不是所以自動轉型,又因為2為truthy所以自動轉型為ture。
2.''為falsy在邏輯運算子中自動轉型為false,在||的左側如果為false則執行右側所以執行123
3.''為falsy在邏輯運算子中自動轉型為false,但是有!所以false倒轉為true,在||的左側如果為true則執行左側所以執行!'',然後!''為true。
直接看顯性(explicit)轉型的範例
```javascript=
console.log(Boolean(''),typeof(Boolean('')))//false boolean
console.log(Boolean('123'),typeof(Boolean('132')))//true boolean
console.log(Boolean([]),typeof(Boolean([])))//true boolean
console.log(Boolean({}),typeof(Boolean({})))//true boolean
console.log(Boolean(undefined),typeof(Boolean(undefined)))//false boolean
console.log(Boolean(null),typeof(Boolean(null)))//false boolean
```
從上面的範例發現到只要判斷各型別資料在布林裡為真值或偽值就可以知道被轉型為true或是false
## 數字的轉型
### 數字的隱性(implicit)轉型
數字轉型相較於Boolean與String的自動轉型有那麼一 ~~(億)~~ 點不同
直接看以下範例吧
#### 1.在+號裡
```javascript=
console.log(+'123',(typeof (+'123')))//123 number
console.log(true+1,(typeof(true+1)))//2 number
console.log(false+1,(typeof(false+1)))//1 number
console.log(null+123,(typeof(null+123)))//123 number
console.log(undefined+123,(typeof(undefined+123)))//NaN number
```
**注意**
只要+號不與字串相連,其他型別就不會被轉成字串
#### 2.在-號裡
```javascript=
console.log(-'123',(typeof (+'123')))//-123 number
console.log(true-1,(typeof(true-1)))//0 number
console.log(false-1,(typeof(false+1)))//-1 number
console.log(null-123,(typeof(null-123)))//-123 number
console.log(undefined-123,(typeof(undefined-123)))//NaN number
```
#### 3.在乘(*)、除(/)裡
```javascript=
console.log('123'*'2',(typeof ('123'*'2')))//246 number
console.log('123'/'2',(typeof ('123'/'2')))//61.5 number
console.log('hello'/'2',(typeof ('hello'/'2')))//NaN number
console.log(null*1,(typeof (null*1)))//0 number
console.log(null/1,(typeof (null/1)))//0 number
console.log(false*1,(typeof (false*1)))//0 number
console.log(false/1,(typeof (false/1)))//0 number
console.log(true*55,(typeof (true*55)))//55 number
console.log(true/1,(typeof (true/1)))//1 number
console.log(undefined*2,(typeof (undefined*2)))//NaN number
console.log(undefined/2,(typeof (undefined/2)))//NaN number
```
**注意**
數字字串只要遇到乘、除運算子就會轉為數字計算,如果不能計算就會呈現NaN
### 數字的顯性(explicit)轉型
一樣直接上範例
```javascript=
console.log(Number('123'),(typeof(Number('123'))))//123 number
console.log(Number(false),(typeof(Number(false))))//0 number
console.log(Number(true),(typeof(Number(true))))//1 number
console.log(Number(null),(typeof(Number(null))))//0 number
console.log(Number(undefined),(typeof(Number(undefined))))//Nan number
console.log(Number('hello'),(typeof(Number('hello'))))//Nan number
console.log(Number('123ok'),(typeof(Number('123ok'))))//Nan number
```
從上面的數字轉型的範例得到以下表格的結論
|型別|轉換為數字型別|
|:--:|:---:|
|Boolean|true轉換為1、false轉換為0|
|string|數字字串會轉為數字,,空字串轉為0會根據+-決定所轉數字的正負|
|null|0|
|undefined|無法轉換|
## 邏輯運算子==與!=的轉型
在非嚴謹模式下==、!=會直接比較值,而不是型別。
```javascript=
console.log(null==undefined)//true
console.log(null!=undefined)//false
console.log(null==0)//false
console.log(null!=0)//true
console.log(null==null)//true
console.log(null!=null)//false
console.log(null!=true)//ture
console.log(null==true)//false
console.log(null!=false)//true
console.log(null==false)//false
console.log(undefined==0)//false
console.log(undefined!=0)//true
console.log(undefined!=true)//true
console.log(undefined==true)//false
console.log(undefined!=false)//true
console.log(undefined==false)//false
console.log(true=='1')//true
console.log(true==1)//true
console.log(false=='0')//true
console.log(false==0)//true
console.log('123'==132)//true
console.log(''==0)//true
```
這邊可以看到null、undefined在==與!=邏輯運算子中的轉型又與數字、字串、布林的轉型不同。
只要遇到 == 或 !=先比較值
null == 0 為false,因為null沒有值,0的值為0。
null == '' 為false,因為null沒有值,''的值為''。
null == undefined 為true,因為null沒有值undefined也沒有,''的值為''。
true 在==中會被轉成1、false會被轉為0
從上面的邏輯運算子轉型的範例得到以下表格的結論
|型別|在==或!=轉換後的型別|
|:--:|:---:|
|Boolean|true轉換為1、false轉換為0|
|string|數字字串會轉為數字,空字串轉為0,此外都為NaN|
|null|沒有值|
|undefined|沒有值|
參考資料
---
[ㄟ問你喔,強制轉型是什麼?轉換型別有規則可循嗎?(布林值、字串篇)](https://karennnnovelty.medium.com/%E3%84%9F%E5%95%8F%E4%BD%A0%E5%96%94-%E5%BC%B7%E5%88%B6%E8%BD%89%E5%9E%8B%E6%98%AF%E4%BB%80%E9%BA%BC-%E8%BD%89%E6%8F%9B%E5%9E%8B%E5%88%A5%E6%9C%89%E8%A6%8F%E5%89%87%E5%8F%AF%E5%BE%AA%E5%97%8E-%E5%B8%83%E6%9E%97%E5%80%BC-%E5%AD%97%E4%B8%B2%E7%AF%87-a9d6d6cc91d)
[ㄟ問你喔,強制轉型是什麼?轉換型別有規則可循嗎?(數字型別篇)](https://karennnnovelty.medium.com/%E3%84%9F%E5%95%8F%E4%BD%A0%E5%96%94-%E5%BC%B7%E5%88%B6%E8%BD%89%E5%9E%8B%E6%98%AF%E4%BB%80%E9%BA%BC-%E8%BD%89%E6%8F%9B%E5%9E%8B%E5%88%A5%E6%9C%89%E8%A6%8F%E5%89%87%E5%8F%AF%E5%BE%AA%E5%97%8E-%E6%95%B8%E5%AD%97%E5%9E%8B%E5%88%A5%E7%AF%87-690586a391b1)
[JavaScript type coercion explained](https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/)
[javascript中tostring()和valueof()的用法及兩者的區別](https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/273528/)
[你懂 JavaScript 嗎?#8 強制轉型(Coercion)](https://cythilya.github.io/2018/10/15/coercion/#%E9%9A%B1%E5%90%AB%E7%9A%84%E5%BC%B7%E5%88%B6%E8%BD%89%E5%9E%8Bimplicit-coercion)