# Web企業運算_Week9_許家維
### 學習清單
1. Typescript 基礎練習<br>參考文章 : https://ithelp.ithome.com.tw/articles/10214714
2. Promise 用法練習
3. JS 基本型別複習
4. Canvas 詳細功能複習(專案需求)
5. HackMD 連結 : https://hackmd.io/S1Bls2JkSQG4Yz_dW5CcRQ?both
### Code
**姓名速配指數**
app.components.html
```
<div class="card">
<h1>姓名配對指數</h1>
<h4>輸入雙方姓名即可測試</h4>
A : <input type="text" [(ngModel)] = name1 placeholder="名字1">
<br>
B : <input type="text" [(ngModel)] = name2 placeholder="名字2">
<br>
{{name1}} 和 {{name2}} 他們的配對指數為 {{score}} 分ㄛ❤❤❤❤
</div>
<router-outlet></router-outlet>
```
style.css
```
* {
font-family: 微軟正黑體;
background-color: rgba(0, 0, 0, .2)
}
.card {
text-align: center;
/* border : solid 1px black; */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
padding: 50px 120px;
border-radius: 10px;
background-color: rgba(255,255,255,.5);
color: #ed2553;
}
.card > * {
background-color: transparent;
}
input {
padding: 5px;
border : solid 1px #ed2553;
background-color: rgba(255,255,255,.5);
color: #ed2553;
margin-bottom: 25px;
}
```
app.module.ts
```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
<!-- 原有框架上新增form模組 -->
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
<!-- import 模組 -->
FormsModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
app.components.ts
```
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'ng2';
<!-- name1 name2 雙向綁定至畫面上 -->
name1 = '';
name2 = '';
<!-- 建立並初始化物件 -->
constructor() {
}
<!-- 簡單的計算姓名指數演算法 -->
get score() {
<!-- 轉成全英文小寫字母 -->
let letters = (this.name1+this.name2).toLowerCase();
let sum = 0;
for(let i=0; i< letters.length;i++){
<!-- 返回0到65535之間的整數(utf-16code) -->
sum+=letters.charCodeAt(i);
}
return (sum % 101);
}
}
```
完工畫面

### 成果
**TypeScript**
* 由 Microsoft 推出,擁有型別系統(Type System)與介面(Interface)設計的語言,TypeScript 可以想成他是在原生 JS 上包裝上一層新的語法
* 優勢:型別系統 Type System
* 藉由 TypeScript 在 IDE 上的 Autocomplete Feature 來協助開發並且防止錯誤
* 
* 可自由設定讓專案編譯成我們想要的 JS 版本(ES5、ES6...)
* ```npm install typescript -g ``` : 下載typescript 指令工具 (要在有Node的環境下)
* ```$ tsc --init ``` : 此時你的專案會出現一個名為 tsconfig.json 的檔案(TS設定檔)
* ```$ tsc file.ts ``` : 將ts檔轉成ES5(預設)的js檔
* ```$ tsc –p src –w ``` : 存檔時可直接將所有資料夾內的ts檔編譯成js檔
* TS 型別
* 原始型別 :包含 number, string, boolean, undefined, null, ES6的symbol、void
* 物件型別 :
* 基礎物件型別:包含 JSON 物件,陣列(Array或T[]),類別以及類別產出的物件(也就是 Class 以及藉由 Class new 出來的 Instance)
* TypeScript 擴充型別:即 Enum 與 Tuple,內建在 TypeScript
* 函式型別 Function Types:類似於 (input) => (Ouput) 這種格式的型別,後面會再多做說明
* 明文型別 : 一個值本身也可以成為一個型別,比如字串 "Hello world"
* 特殊型別 : any、never(TS 2.0)、unknown(TS 3.0)..
* 複合型別 : union 、 intersection
* Getter : get(),用來取得指定屬性的值,不接受參數
* Setter : set(),設定指定屬性的值,可以有一個參數
* 範例
```
object = {
a:7,
get b() { return this.a+1; },
set c(x) { this.a = x/2; }
};
```
**Promise 概念**
* 建立Promise : ```var promise = new Promise ( (resolve, reject) => { ... } )```
1. 在建構函式傳入 executor 函式
2. 可在函式中執行非同步作業
3. 順利完成時,**呼叫resolved(value)回應所得資料**<br>Value 通常為一合法 Javasript值<br>此時,**進入Fulfilled(已實現)狀態**
4. 發生錯誤時,**呼叫reject(reason)回應錯誤資訊**<br>reason通常為error物件<br>此時,**進入Reject(拒絕)狀態**
* 可使用 **then** 獲得最終處理結果及進行接續行為
* EX.```var newPromise = promise.then( onFulfilled, onRejected )```
* ```onFulfilled = (value) => {...}```
* 在 Promise 的 executor 中呼叫 **resolve** 方法會進入此方法中(狀態Fulfilled已實現時)
* 傳入值
* 由上層 executor 透過 resolved(value) 傳入的資料
* 從上層 onFulfilled 或 onRejected 方法直接 return value
* 不區分值是從 onFulfilled 還是 onRejected 傳出來 (**因在 onFulfilled 或 onRejected 不發生錯誤 / 不呼叫 reject 時,都會進入下個 onFulfilled 中**,當然也包括回傳值)
* 回傳值
* value 值 (可以從新Promise 物件 then 中 onFulfilled 方法參數中取得)
* Promise 物件 : 當有需要再處理一個非同步作業時使用<br>**自己建立一個 Promise 取代 then 回傳的新 Promise 物件value**
* thenable 物件
* ```onRejected = (reason) => {...}```
* 在 Promise 的 executor 中呼叫 **reject**方法會進入此方法中
* 傳入值:
* 上層 executor 透過 reject(reason) 傳入的錯誤發生資訊
* 從上層 onFulfilled 或 onRejected 方法直接呼叫 Promise.reject(reason)
* 回傳值:value, promise 或 thenable ....etc
* 多數使用情境下在 then 中只會定義 onFulfilled 方法
* 錯誤多會交由 promse.catch 作攔截處置
現在來看一個簡單的範例
```
// promise 成功要執行的方法
function onFulfilled (value) {
console.log(value) // 'success'
}
// promise 失敗要執行的方法
function onRejected (reason) {
console.log(reason.message) // 'wrong !!'
}
// then 處置 promise 成功或失敗要做的事情
doSomethingAsync()
.then(onFulfilled, onRejected)
// 通常不特別在 then 中定義 onRejected 方法
// 多數使用 catch 直接捕捉/處理上方連鎖發生的錯誤
doSomethingAsync()
.then(onFulfilled)
.catch(onRejected) // 等同 then(undefined, onRejected)
```
* ```Promise.all( [promise1, promise2 ....] ).then(onFulfilled). catch(onReject)```
* 所有 promise 都 resolve 後才會進入 onFulfilled
* onFulfilled 中傳入的 value 為**陣列格式**,**保存各 promise 回傳的值**
* **陣列順序與執行順序無關**
* 所有 promise 其中任一發生錯誤或 reject 情況則馬上回傳
* 直接建立具狀態的promise物件
* ```Promise.resolve(value).then(onFulfilled, onRejected)```
* ```Promise.reject(reason).then(onFulfilled, onRejected)```
*
### 心得
這週上的觀念比較多,包含非常重要的Promise及A與ngular 搭配的Typescript兩大觀念。目前先對於這兩個大觀念做一個基礎的複習,後面幾周會再多練習幾次,直到熟悉觀念為止。自己的Javascript沒有學的特別好,所以最近花的時間多在JS的基礎型別、Function觀念等等,希望可以透過練習慢慢補強自己較弱的JS部分。