AppWorks School
你被派到銀河隊調查組,
被穿越時空的大木博士要求用 JS 寫出你的第一隻神奇寶貝
你選擇了小火龍,一開始你這樣寫
後來聽了博士助手子華建議,你決定用個object包裝
大木博士心血來潮,要你再創兩隻神奇寶貝
ctrl+c、ctrl+v
你發現每個神奇寶貝都有 名字
、HP
、STR
、攻擊
四個東西
那不然把它寫成一個通用的 設計圖 好了
我們只是完成設計圖,沒有依照設計圖把神奇寶貝創出來
這個時候你就創好三隻活生生的神奇寶貝了
子華提醒你,火系要會生火,而且應該有火屬性!
應該為火系創一個類別
可是每個火系都是神奇寶貝,應該有共用的地方
子華突然想到,神奇寶貝都會攻擊,可是各個屬性攻擊不同
火系神奇寶貝子攻擊時會噴火、水系的會噴水、草系的…
火箭隊趁子華去開會,潛入研究室偷改小火龍的數值
你趕緊向組員道歉,一行一行看code決定用這樣的方式挽救
火箭隊又出沒,但他們這次發現改不動,你在旁邊滑ptt呵呵笑
任務一、產生一隻小火龍
物件內通常會包含 屬性Property
、方法 Method
屬性Property:該物件的資訊。
方法 Method:定義該物件的功能。
任務二、產生御三家
既有物件拆成class
依照class 實際產生物件
O
減少重複程式碼
易修改
任務三、創造火系類別
重複使用相同程式碼,減少浪費重複工作時間
呼叫父層class的方法
任務四、各屬性不同的攻擊方式
先繼承、修改當中函式,爸媽和孩子的方法可產生不同結果
每個方法在不同class上會有不同結果
! 方法名稱要相同
O
不會動到既有程式
好維護
緊急任務、避免資料遭更動
保護資訊、不被輕易修改
#ES2019才支援,包含 public,protected,private
一條一條寫程式,依照排序讓code執行
如果不用物件導向
物件導向
OOP : 物件導向,以物件為核心,減少重工、提高開發維護效率的概念
Object 物件
class 類別 : 設計圖,分門別類
Instance 實體化 : class → object
Abstraction 抽象化 : object → class
Inheritance 繼承 : 重複使用相同程式碼,減少浪費重複工作時間
PolyMorphism 多型 : 一個子類繼承多個父類。相同名稱處理不同功能
Encapsulation 封裝 : 將屬性、方法、建構式封入類別,避免外部干擾跟誤用
MDN - new operator
React - DOM界的彼方 Day 10: ES6篇 - Class(類別)
從不懂,到玩上手的Python語言 DAY26-物件導向設計
PTT - 物件導向的好處是…(JAVA)
初心者向けに徹底解説!オブジェクト指向とは?
オブジェクト指向の「カプセル化」とはなにか?超わかりやすく解説します!
非物件型別(原始型別Primitive type):
- Number
- String
- Boolean
- null
- undefined
- bigInt
包含browser內的document, localstorage都是物件
在ES6後 有了class跟constructor
這樣我們就創建好一個可重複使用且帶有Property的物件了
透過prototype
可以發現到class可以做到的事情,用function也做的到
另外你可能也會想到,function的版本其實可以寫得簡單一點
不需要用到prototype
是可以達到一樣的功能,但就會造成每次都會產生一個新的speak
function,會造成記憶體的浪費
類似於我們在寫React function component時,function內沒有被hook管理的變數、funcion、物件,會被重新宣告
用prototype寫可以避免這個問題,可以想像成function裡面寫的東西是每次被物件化時,會被執行的程式碼等同於class內的constructor
,用prototype產生的method則是被呼叫時才會執行
在ES6中的class
(類別)語法,並不是真的是以類別為基礎class-based
的物件導向,在骨子裡仍然是以原型為基礎prototype-based
的物件導向,它只是個語法糖syntactical sugar
。加入Class(類別)語法的目的,並不是要建立另一套物件導向的繼承模型,而是為了
語法糖:讓程式更加簡潔,有更高的可讀性
function
去寫,雖然可以達到一樣的功能,但就寫的比較麻煩可以注意到我們用新的
class
取代被繼承的class
的speak method
,這牽扯到了javascript
的原型鏈prototype chain
,簡單來說,一個物件本身如果本身有這個method,就會被執行,如果沒有的話,他就會往上層(被繼承的物件的__proto__
)去找,如果有,就會執行,如果都沒有,就會是undefined
很簡單,只要在constructor
的內容第一行打上super()
,並且裡面帶上原class consturctor
所需的參數即可
class
要創建constructor
,一定要在寫上第一個this
之前加上super()
super()
的概念可以理解成:將原本的class
內容先寫一遍function
搭配prototype
產生出來的method
或是class
的寫法,又稱作Prototype method
原型方法class
中的 static method
靜態方法class
,然後想要計算兩者之間的距離,可以怎麼做?static
你可能只能這樣做static
的寫法static
就是一個class
的method
,可以幫把當作一個function
來使用,但只存在於class
中,無法被物件使用,白話文說,就是沒辦法透過被new的物件去呼叫他class
內部function
如何撰寫的,只要執行就好Getter
用來拿物件的property
this.color
改成this._color
是想要避免被外部直接更改,但如果知道變數的命名,還是可以直接修改的Setter
用來設定物件的property
Setter
可以用來當作一個判斷式、如果符合才更改變數method
名稱去拿取或更改Object
的Property
,同時避免被直接存取if
) 或資料處理 (數據轉換)class內的參數還是有方法可以避免被直接修改的,詳情可以搜尋
public/private class fields
以Stylisy product page舉例,我們一般的寫法可能會像是這樣
由一個主要的functionproductDetail
去呼叫其他function
可以看到很多同樣的參數被傳遞來傳遞去的,可能會衍伸出以下問題
這樣一來,當別人要複製你的code,僅需要整包class複製
參數也不需要一直重複宣告、傳遞
同時可以把主要架構放在constructor,較容易閱讀
javascript
中,大部分的東西都是物件class
是一個語法糖,單純用function也可以寫出一樣的程式static
僅限於class使用,被物件化new XXX()
的無法使用call
, apply
, bind
(強制綁定 this
的調用)如果直接調用函式,此函式的 this 會指向 window,以下兩個範例都是直接調用函式,所以都是指向 window
小結: 無論在哪一層,純粹的調用方式 this 都會指向 window
如果 function 是在物件下被called,那麼 this 則會指向此object,無論 function 是在哪裡宣告
call
, bind
, apply
這三者都可以傳入新的 this 給予函式使用,使其作為 this 所指向的物件,三者僅是使用方法不同
call
fn.call(this, arg1, arg2..., argn)
Example 1: 強制綁定18,永遠的18歲!
Example 2: 除了傳入給定 this 的參數之外還可以傳入其他argument
apply
fn.apply(this, [arg1, arg2..., argn])
call
類似, 只是第二個參數是陣列而且必須是陣列call
bind
fn.bind(this, arg1, arg2..., argn)
Example 1
Example 2: object call + bind
call
, apply
, bind
: 強制綁進去的this
this: Simple call, Object method, DOM event handler, Constructor
Regular function v.s Arrow function
Strict mode
call, apply, bind