JavaScript | ES6 中最容易誤會的語法糖Class - 基本用法
文章推薦指數: 80 %
Instance 能夠使用Class 內的Method,並藉由Method 存取Object 內的資料。
咦?就算沒寫過,但這樣看起來似乎和JavaScript 的Constructor 及Instance ...
UpgradeOpeninappHomeNotificationsListsStoriesWritePublishedinEnjoylifeenjoycodingJavaScript|ES6中最容易誤會的語法糖Class-基本用法Class間的Inheritance(繼承)前言Hi!本來在之前想和Promise、Fetch一起完成的ES6小小三部曲,一直拖到現在才真正動工,其實本來沒有想要另外學了,但因為最近讀Refactor發現善用Class也是很好的重構技巧之一,所以決定花點時間讓自己熟悉一下。
Class先來解釋一下標題好了,Class是JavaScript中最容易被誤會的語法糖了為什麼會被誤會?如果各位讀者有寫過其他像是Java的Class-Based物件導向語言,都會知道下面幾件事情:分成Class和Object兩種。
Class內部會描述Properties和Method。
Class能建構出Object,也被稱作Instance。
Instance能夠使用Class內的Method,並藉由Method存取Object內的資料。
咦?就算沒寫過,但這樣看起來似乎和JavaScript的Constructor及Instance差不多對吧?對!但是差別在於第一點所說的「分成Class和Object兩種」擁有Class才能產生出對應的Instance,這是與JavaScript差別最大的地方。
在JavaScript的Prototype-Based物件導向中,不區分Class和Object所有的東西都可以是Object,且不一定需要經過Class或Constructor才能建立Instance,直接操作Prototype也能辦到。
再來,如果在Java中要做Class間的繼承,得在定義Class時指定要繼承的父類別。
在JavaScript中則是以改變Constructor的Prototype來使用其他Constructor的Method。
這些差別都是取決於物件導向是基於Class或Prototype,因此就算ES6新增了一個Class保留字用來當Constructor創建Instance,也不代表它物件導向的方式會變成Class-Based,只是被Class包裝的Prototype-Based而已。
所以千萬不要搞混囉!Class只是簡化了JavaScript中操作Constructor的語法糖而已。
ConstructorConstructor是建構器,可以用它產生擁有相同Properties的Object,例如大家都熟悉的:Person內裡面有三行程式碼,來看看它們分別是什麼:name是經過Person創建出來後會帶的OwnProperties(自有特性),會在呼叫Constructor時當作參數傳入。
state是一個Privatevalue(私有值),它只存在於Constructor創建Instance時另外產生的環境。
雖然state不是Instance的OwnProperties,但是透過getForm便能夠取得state的值,這種讀取Privatevalue的方式稱作PrivilegedMethod(特權方法)。
那接著進入ES6時期的Constructor,Class版本又會是什麼樣子:有沒有煥然一新的感覺?用Class來宣告Constructor在語義上面會更清楚,不像之前只能透過字首的大小寫來判斷是否為Constructor,且還有可能會有未遵照規則導致使用錯誤的情況發生。
透過new呼叫時傳入的參數會由Class內的constructor給接收,並在同一區塊建立PublicProperties,而Method的部分則是在constructor外做描述或存取資料,PrivateValue就存放在Method中,依然無法從Instance中取得。
然後這邊是個很棒的時間,可以讓我們驗證Class的操作是否仍然為Prototype,如果是透過Constructor建立的Instance,應該會擁有相同的Prototype:透過Constructor建立的Instance,會擁有相同的PrototypeInheritance繼承的話在Class上也變得方便許多,想當初如果要Constructor上處理繼承,就得使用call在Constructor創建Instance時來指定this呼叫另一個Constructor,像是這樣子:看起來有些複雜了對吧?但如果是Class只需要利用extends和super便可輕鬆處理Constructor間的Inheritance:上方在定義Employee時另外用了extends指定了Person,這麼一來就等於是繼承了Person的Properties和Method,但為什麼在Employee中的constructor中還要使用super把name傳給Person呢?因為Employee中也有constructor當子類別自身也需要透過constructor建立Properties時,就需要使用super另外指定要送給父類別的值,否則就Person來說,創建Instance時將兩個值送入Employee,Person根本不曉得哪一個才是要被指定成name的資料,這裡大家可以想像成是用call來呼叫另一個Constructor的感覺。
也就是說了,如果當今天不需要透過Employee創建Properties,僅僅是增加Method,那super就可以省略,因為所有的參數都會是給Person的:最後記得那個可怕的SuperCall(超呼叫)嗎?當子類別的Method要呼叫父類別的Method執行就叫SuperCall,在未有Class時,仍然是需要使用call將this指定給父類別Prototype的Method做執行:儘管我已經將例子盡量簡化了,看起來還是很麻煩,且Person要被SuperCall的Method也得另外設置在Prototype中。
但是到Class時代後一切便不同了,答案就在運用上方提到的super,既然是透過傳送參數給它來創建Properties,那也可以透過super直接呼叫父類別中的Method:是不是簡潔多了?透過super便不需要再手動處理Prototype。
那依照慣例,在Inheritance這個段落的結尾也來驗證Class間的Inheritance是否也同樣是在操作Constructor的Prototype,如果是的話,那子類別Employee的Prototype應該會等於父類別Person,而Instance的Prototype依然指向Employee:由luck繼承自Employee,Employee又繼承自Person,又稱為Prototypechain(原型鏈)到這裡應該可以清楚明白,就算眼睛看見的是Class,寫下的也是Class,但骨子裡操作的卻還是Prototype。
學會在Class中創建Instance、Inheritance、SuperCall後,接著來看看Class提供的StaticMethod(靜態方法)!Static在Class內的Method可以加上static前綴,使它變成StaticMethod(靜態方法),被定義為StaticMethod可以直接以Constructor呼叫,但創建出來的Instance是無法使用它的:Getter&Setter前綴詞其實不只有static,連存取器的get及set也可以在Class中作定義:經常用於不想Instance直接存取的狀況,所以利用Getter和Setter來假裝操作Properties,在設定及取值時都先經過一些邏輯判斷再決定怎麼處理。
以上是對於Class的一些整理,上半部主要是在比較Class出現前後對Constructor及Inheritance的操作有什麼差別,結尾講解了Static和存取器在Class中的使用方式。
如果文章中有任何問題,或是不理解的地方,都可以留言告訴我!謝謝大家!參考資料https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Classeshttps://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Details_of_the_Object_Modelhttps://ithelp.ithome.com.tw/articles/10185583https://www.arthurtoday.com/2012/01/prototype-based-language.htmlMorefromEnjoylifeenjoycodingThelearnprocessofwebsitecode.ReadmorefromEnjoylifeenjoycodingGetstarted神Q超人1.6KFollowers82年次,單純相信努力不會騙人FollowRelatedJavaScriptandPrototypeWhatisJavaScript?DateObjectinJavascriptJavascriptdateobjectsrepresentasinglemomentintimeinaplatform-independentformat.Date()objectcontainsanumberthatrepresents…AxiosThrottleThisweekIwastaskedwithuploading500,000userrecordsintoZendesk.NullishCoalescingOperatorIntroductionHelpStatusWritersBlogCareersPrivacyTermsAboutKnowable
延伸文章資訊
- 1你懂JavaScript 嗎?#21 ES6 Class | Summer。桑莫。夏天
關於ES6 Class,我們先再次檢視先前提過的Widget 與Button 範例。 class Widget { constructor(width, height) ...
- 2JavaScript Class (類別) - Shubo 的程式開發筆記
JavaScript中沒有真正的「類別」實體。 class 宣告出來的本體是「函式」。 換句話說, class 只是宣告函式的一種特別的 ...
- 3JavaScript Class Fundamentals: Introduction to ES6 Class
A JavaScript class is a blueprint for creating objects. A class encapsulates data and functions t...
- 4Classes - JavaScript - MDN Web Docs
ECMAScript 6 中引入了類別(class) 作為JavaScript 現有原型程式(prototype-based)繼承的語法糖。類別語法並不是要引入新的物件導向繼承模型 ...
- 5JavaScript Classes - W3Schools
Class methods are created with the same syntax as object methods. Use the keyword class to create...