# 第三週共筆筆記 - <br> 10/19 核心篇第三堂:型別轉換
###### tags: `核心篇`、`六角學院`、`2022JS直播班`
[上課講義](https://hackmd.io/9ZYAdktRT3e4GnKCVzI74g)
### 共筆簽到區
Barret
Data
### 正課開始!~~~~
> 實際運用 會用顯性轉換
> 會用嚴格比較!!!
> 實務雷包 小心別亂採
### 課前小考
```javascript
// 第一題 是函式也是物件
function fn(params) {
}
fn.myName = '小明';
console.log(fn.myName); // 這樣是可以的嗎?
```
```javascript!
// 第二題
console.log(1 == '1');
// 請問結果為?
// true、false
console.log(1 === '1');
// 請問結果為?
// true、false
```
```javascript!
// 第三題
console.log(1 + true); // 請問結果為?
// 1 1
// 2 2
// 3. '1true'
// 4. 其它
```
### 型別
#### 原始型別
```javascript!
console.log(typeof true); //boolean
console.log(typeof 1); //number
console.log(typeof Nan); //not a number > number
console.log(typeof "true"); //string
console.log(typeof undifined); //undifined
console.log(typeof null); // null > object
console.log(typeof 100n); // bigint
console.log(typeof symbol(1)); // 原始型別 symbol
console.log(symbol(1)); // symbol(1)
```
#### 物件型別
>除了原始型別外,其他都是物件型別
```javascript!
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function() {}); // function > object
console.log(typeof /12345/); // 正規表達式 > object
```
#### 如何判斷是不是物件?
```javascript!
const obj ={
// 屬性:property
// key : value
name:'卡斯伯'
}
obj.name = 'Barret';
console.log(obj);
```
> 物件型別,可以自由擴增屬性
```javascript!
const arr = [];
arr.name = '我是一個陣列';
console.log(arr);
// 請問陣列有沒有被加上奇怪屬性? > 有沒有被塞進去
// 有,能塞進去!
// 實戰中,千萬別這樣幹!!!會被釘在牆壁上
```
```javascript!
const fn = function () {};
fn.name = "我是一個函式"; //在實戰中,可能會用到。
// console.log(fn);
console.dir(fn); //看到物件裡面的內容
//函式 作為一般物件使用,塞入其他東西
```
> 原始型別,不能擴增屬性
```javascript!
let num = 1;
num.myName = '我是一個數值';
console.dir(num);
```
```javascript!
let num = 1;
num.myName = '我是一個數值';
console.dir(num);
```

> 當瀏覽器顯示 DOM 是一個標籤時,就必須改用console.dir
```javascript!
const p = document.getElementById('p');
console.log(p);
console.dir(p);
```

### 型別方法在哪裡?
```javascript!
let str = ' i am 筆記 ';
console.log(str);
cnosole.log(str.trim()); //去掉頭尾空白
//實戰請不要這樣寫!!!
// 這些方法都可以從 MDN 找到
```
[trim()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
#### 原始型別包裹物件
```javascript!
console.log(String);
console.dir(String);
```
```javascript!
let str = new String(' i am 筆記 '); //這是一個物件
console.log(str);
console.log(str.trim());
```
```javascript!
let str2 = new String(' i am 筆記 ');
console.log(typeof str);
console.log(str == str2); //false
// 髒東西來了
str.myName = "我是一個字串";
console.log(str);
```
### 型別轉換
> 顯性轉換 / 隱性轉換
```javascript!
let pricr = 100; //Number
console.log(price);
cnosole.log("100");
price = '新台幣 100 元'; //String
console.log(price * 5); //這時候就會出現 Nan,無法正確運作
```
> 實戰中可能會遇到,所以要了解型別轉換的類型
#### 顯性轉換
> 1-1 原始型別包裹物件 Number, String
```javascript!
let price = 100;
console.log(String(price)); //String
console.log(BigInt(price)); // 100n ->Bigint
console.log(Symbol(price)); // Symbol(100) -> Symbol
```
> 1-2 原型方法
```javascript!
// toString
console.log(Number);
console.dir(Number);
conosole.log(typeof price.toString()); //String
// 要注意原型鏈中,有沒有該方法!!! (他有沒有原始型別包裹物件)
console.log(Undefined);
console.log(Undefined.toString()); // 會報錯,因為Undifined 沒有這個方法
```
> 1-3 數值型別的方法
``` js!
console.dir(Number);
console.log(Number.parseInt('100元')); //String > 100
// 轉型都不會使用他
cnosole.log(Number('100元');
```
``` javascript!
connsole.log(parseInt('100元'));
console.log(window.parseInt)
```

> 2-1 運算子 正負'一元'運算子(套用 number)
```javascript!
console.log(1 + "1"); //這是二元
console.log( +'1'); //typrof > number
console.log( + true); //typeof > number //1
console.log( +'50元'); //typeof > number //Nan
console.log( -'50元'); //套用number 轉型 //Nan
```
> 3 邏輯 not 運算子 (否定的意思) [轉型為boolean]
```javascript!
console.log( !true); //false
console.log( !false); //true
console.log(!0); //true
cnosole.log(Boolean(0)); //會先把0轉成布林,才繼續計算
console.log(!"1"); //false
//下面是實戰中常用語法
console.log(Boolean('1'));
console.log(!!'1'); //用兩個驚嘆號轉 上面那一行
```
#### 隱性轉換
> 1 +運算子 (二元運算子)
```javascript!
console.log(100 + 100); //算數運算子
console.log('我是' + '筆記') ; //字串運算子
```
```javascript!
console.log(1+'1') ; //字串運算子 > 11
cnosole.log(1 + true); //算式運算子 > 2
console.log(1+ {}) ; // 字串運算子 > 1[object]
conosle.log(String ({}));
conosole.log(1+ []); //字串運算子 >
```
```javascript!
console.log(1 + 1n); //error Bigint 無法跟其他數值轉換;
console.log(1 + Symbol(1)); //error symbol 不能轉成數值;
console.log(true + Symbol(1)); //error symbol 不能轉成數值;
console.log('true' + Symbol(1)); //error symbol 不能轉成字串;
console.log({} + Symbol(1)); //error symbol 不能轉成字串;
console.log(1 + {a:1}); // 1{a:1} 正確是 1[object object]
// 物件轉型時,會轉成 [object]
console.log(1 + [1,2,3]); // 1{a:1}
```
> 2 算數運算子 (- / *) 一律作為Number
```javascript!
console.log(1 + '1'); //字串
console.log(1 - '1'); //數值
console.log(100 * true); //Ans:100 數值
console.log(100 - true); //99
```
```javascript!
let price = '100';
conosle.log(price * 1); //不建議這樣用,建議還是先用顯性轉化
```
> 3 例外狀況 BigInt
```javascript!
console.log(1n * 100); //error 無法轉型
console.log([100] * 100) ; //10000 > 轉型為Nmber
console.log([100, 1] * 100) ; // 100100 > 正確是 Nan
```
> 陣列轉型
```javascript!
console.log([100].toString()); //100
console.log([100,0].toString()); //100,0
console.log([100,0].toNumber()); //Nan
```
### 型別比較 (寬鬆相等;嚴格相等)
> 寬鬆相等;嚴格相等
```javascript!
//嚴格相等:值與型別,完全相同才能回傳 true
console.log( 1 === '1');
// 寬鬆相等:只要值相等,就會true
console.log(1 == '1');
```
> 嚴格相等的例外狀況 (要認真記一下)
```javascript!
false
conosle.log(NaN === Nan);
console.log(undefined === null);
console.log({} === {});
console.log([] === []);
console.log(new Number(0) === new Number(0)); //原理:記憶體位置不同
true
console.log(0 === -0);
```
> 寬鬆相等的規則
Number,String, Boolean 通通轉數值型別
null, undefined 不轉型,都是false 但是 null 與 undefined 相比 true
```javascript!
console.log( null == 0);
console.log( null == '');
console.log( null == 0);
console.log( null == false);
console.log( null == undefined);
```
BigInt(數學值)
```javascript!
console.log(Number);
Number.MAX_SAFE_INTEGER; //最大的安全數值
console.log(9007199254740991 =='9007199254740991');
console.log(9007199254740993 =='9007199254740992'); //false
--> 掉入陷阱,因為超過安全數值範圍,所以精準度下降 輸出會是 true
console.log(9007199254740993n =='9007199254740992'); //false
--> BigInt 轉型為數值,沒有最大安全值問題,可以比對超過安全數值的數值。
cnosole.log(100n * 100n);
```
物件與非物件
> 使用原始型別包裹物件做轉型
```javascript!
console.log([0] == 0); //true
console.log('[object object]' == {}); //true
String({}) ; //[object object];
```
> 例外狀況 Boolean
```javascript!
console.log([] == false); //true
console.log(Number[]); //0
console.log([1] == true); //true
console.log([2] == true); //false
--> 死翹翹,前面是二,布林採用數字轉型 變成1
//冷門的例外
let sym1 = Symbol(1);
let sym2 = Symbol(1);
console.log (sym1 == sym2); //false
```
> 真假值說明
```javascript!
if(''){
conosle.log('這段不會運行')
}
if('0'){
conosle.log('這段會運行')
}
if([]){
conosle.log('這段會運行')
}
Boolean[] //true
```
```javascript!
// 實戰中作法
// 判斷陣列內是否有值
// [1,0,.....] 為真值
// [] 為假值
if([].length){
conosle.log('這段會運行')
}
```
> 來 最後一題有趣的題目
```javascript!
1 + {}
'1[object object]'
//相關知識 block
{} + 1
1
{ let a = 1;} +1
```
