### 型別、物件
----
課程聊天室: https://tlk.io/1220js

---
## 型別
> JS 是一個弱型別語言,雖然方便但卻也因此容易出錯
----
## 簡單型別
* string
* number
* boolean
* null - 空值
* undefined - 宣告但沒有值
----
## 複雜型別
* object
* symbol (ES6 版本後出現,較少用)
----
## 型別相關最常進行的行為
#### 比較: === vs ==
----
#### [在 stackoverflow 上前幾熱門的問題](https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons)
----
```javascript=101
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
```
----
#### API 操作與基礎特性
----
## string
----
* `split` - 根據給予的參數將字串分隔成由字串組成的陣列
```javascript=101
var value = 'I am string';
value.split(' ');
// ['I', 'am', 'string']
```
----
* `trim` - 去除頭尾空白
```javascript=101
var value = ' I am string ';
value.trim();
// 'I am string'
```
----
* `toLowerCase` / `toUpperCase` - 轉大小寫
```javascript=101
var value = 'I am string';
value.toUpperCase();
// 'I AM STRING'
```
----
* `match` - 判斷文字是否合乎一定格式
```javascript=101
var value = 'i am in lowercase';
value.match(/[A-Z]/g)
// false
```
----
Exercise -
```javascript=101
var desc = ' item1: task1,item2: task2,item3: task3 ';
function generateItemList(value) {
let result;
...
return result;
}
generateItemList(desc)
// ['item1: task1', 'item2: task2', 'item3: task3']
```
----
## number
----
* `Number.parseInt('數值', 基底)` - 依照傳入基底,將數值轉為整數,基底預設不是 <b>10</b>
```javascript=101
var value = Number.parseInt('123.1');
console.log(value)
// 123
var value = Number.parseInt('0x10');
console.log(value)
// 16
var value = Number.parseInt('0700');
console.log(value)
// 700
var value = Number.parseInt(0700);
console.log(value)
// 448
// 若參數類型不是字串的話,會先將其轉成字串,相當於 toString()
// 0700.toString() -> 448
```
----
#### Number.parseInt('數值', 基底)
###### [如果基底 = undefined, 0(或留空)的話, JavaScript 會:](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
* "0x70" :16
* "0700" : 10 or 8 取決於各自實做
* 其他字串開始:10
:bomb: parseInt 時一定要指定 radix。
----
* `Number.isNaN` - 檢測數值是否為 NaN
```javascript=101
var a = Number.parseInt('abc');
console.log(a.isNaN())
// true
```
----
* `toLocaleString(代碼)` - 轉換成其他格式
```javascript=101
var a = 123456789;
console.log(a.toLocaleString('zh-Hans-CN-u-nu-hanidec'))
// 一二三,四五六.七八九
```
----
* `toString(基數)` - 轉換成文字, 基數預設為 <b>10</b>
```javascript=101
var a = 123;
console.log(a.toString())
// '123'
var a = 0700;
console.log(a.toString())
// '448'
```
----
* `NaN !== NaN`
----
Exercise -
```javascript=101
var desc = '20191220';
var invalidNumber = 'abcd'
function produceChinseDate(value) {
let result;
...
return result;
}
produceChinseDate(desc)
// 二〇,一九一,二二〇
produceChinseDate(invalidNumber)
// NaN
```
----
## null
* `typeof null` -> "object" (bug)
* 正確的判斷方式 -> value === null
* null == undefined -> true
* null === undefined -> false
----
## undefined
* `typeof undefined` -> "undefined"
----
## boolean
在 JavaScript 進行邏輯判斷時,有許多數值會與 `false` 等價,我們稱為 Falsy Value.
----
> Falsy Value:
> | Value | type |
> | -------- | -------- |
> | 0 | Number |
> | NaN | Number |
> | '' | String |
> | false | Boolean |
> | null | Object |
> | undefined | Undefined |
----
Exercise -
```javascript=101
if(0) {
console.log('這裡不會被執行, falsy')
}
if('0') {
console.log('這裡會被執行, truthy')
}
```
----
#### Implicuit Coercions - 強制轉型
```javascript=101
1 + '1' -> '11'
3 + true -> 4
+'1' + 4 -> 5
isNaN({}) -> true
```
###### isNaN 執行前會將參數轉為數字
---
## 物件
> 可以儲存屬性與方法的模型
```javascript=101
var obj = {
propertyA: 'valueA',
methodB: function() {
return 'this is method B'
}
}
```
----
#### 建立方式
實字表示法 v.s. 建構子表示法
```javascript=101
// 實字表示法, 簡潔
var hotel = {
name: 'Quay'
};
// 建構子表示法, 可以模板方式建立多個相似的物件
function hotel(name, rooms) {
this.name = name;
this.rooms = rooms;
}
```
----
#### 建構式 - [建立物件的初始流程](https://hackmd.io/@ChadZ/BkeiXOwRB#/)
----
#### 內建物件
瀏覽器物件 / JavaScript 物件 / 文件物件
----
* 瀏覽器物件 - 與瀏覽器或視窗有關的模型
* Documnet
* History
* Location
* Navigator
* Screen
----
* 文件物件 DOM Tree - 與網頁相關的模型
----
* 全域 JavaSript 物件
* Object
* String
* Number
* Boolean
* Date
* Math
* Regex
----
Api 練習
* `Object.keys()`
```javascript=101
var obj = {a: 1,b: 2};
Object.keys(obj)
// ['a', 'b']
```
----
* `Object.values()`
```javascript=101
var obj = {a: 1,b: 2};
Object.values(obj)
// [1, 2]
```
----
* `Object.assign()` - :bomb: 這是淺拷貝
```javascript=101
var objA = {a: 1};
var objB = Object.assign(objA);
objB.a = 2;
objA.a
```
###### 若要深拷貝,可以考慮用 `lodash.clonedeep()` 或 `JSON.parse(JSON.stringify())`
----
* `obj.hasOwnProperty('property')` - 是否有某個屬性,繼承的不算
```javascript=101
var object1 = new Object();
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// true
console.log(object1.hasOwnProperty('toString'));
// false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// false
```
----
Math
* `Math.random()` - 產生 0 -> 1 之間的亂數
* `Math.floor()` - 回傳比傳入參數大或相同的最大的整數
----
```javascript=101
console.log(Math.floor(5.95));
// 5
console.log(Math.floor(5.05));
// 5
console.log(Math.floor(5));
// 5
console.log(Math.floor(-5.05));
// -6
```
----
Date
----
* `Date.new()` - 回傳距離 January 1, 1970, 00:00:00 UTC 的毫秒數
```javascript101
Date.now()
// 1576763104346
```
----
* `Date.parse()` - 回傳指定參數距離 January 1, 1970, 00:00:00 UTC 的毫秒數
```javascript101
Date.parse('01 Jan 1970 00:00:00 GMT')
// 0
```
----
* `new Date().toLocaleString()`
```javascript=101
var a = new Date();
console.log(a.toLocaleString('zh-Hans'))
// 2019/12/18 下午6:23:14
```
----
* `new Date().getFullYear()`
* `new Date().getYear()`
* `new Date().getMonth()`
* `new Date().getDate()`
----
Exercise -
```javascript=101
var current = new Date();
function generateChineseDateFormat(value) {
let result;
...
return result;
}
generateChineseDateFormat(current)
// 2019年12月20日
```
----
Exercise -
```javascript=101
JSON.stringify(new Date());
```
----
# 型別、物件
----
Ref:
1. [在 stackoverflow 上前幾熱門的問題](https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons)
2. [MDN parseInt](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
----
[範例程式](https://hackmd.io/@ChadZ/JS-MRT-1-EXERCISE)
{"metaMigratedAt":"2023-06-15T02:41:03.618Z","metaMigratedFrom":"YAML","title":"型別、物件","breaks":true,"slideOptions":"{\"title\":\"型別、物件\",\"theme\":\"night\",\"transition\":\"slide\",\"spotlight\":{\"enabled\":false},\"transitionSpeed\":\"fast\"}","contributors":"[{\"id\":\"7da0a1a8-6add-40a7-9acc-950070ff069c\",\"add\":24989,\"del\":18042}]"}