前言
在這系列的課程,我們將總結 JavaScript 全攻略:克服JS的奇怪部分 學習到的知識,並仿效 jQuery 原始碼的架構,來打造一個簡單的 Framwork,取名為 Greetr
。
關於 jQuery的架構可以參考
需求
當我們在打造一個 framework 時,須事先規劃好這個 framework 要具備哪些功能,而不是一股腦的就打開程式編輯器開始寫,以下是這個框架的功能。
當我們告訴它我們的姓(lastname)名(firstname)還有選擇的語言(language)時,它可以用正式(formal)和非正式(informal)的方式和我們打招呼。
支援英文(English)和中文(Chinese)兩種語言。
是一個可重複使用的 library/framework,也就是說,每一個安裝此 framework 的人可以直接使用,不會和它原本程式碼有所衝突。
和 jQuery只需要輸入
$()
一樣,我們可以使用G$( )
來建立物件。支援 jQuery
,可以把 Greetr 產生的訊息直接顯示於 HTML 中。
HTML
1 | <html> |
安全的程式碼 IIFEs
參考:PJChender - 為什麼我們要用IIFEs(Immediately Invoked Functions Expressions)
先前的課程有提到知名的框架通常都會使用 IIFE,避免程式碼使用者和框架的程式碼互相汙染。
1 | (function(global, $) { |
同時,因為我們要讓我們的 framework 能夠取用或改變到全域環境的內容,同時還要支援 jQuery ,因此在參數的地方,我們會帶入 window
和 jQuery
的核心 。
補充:我們還可以加上
;
在最前面,防止前一份 Framwork 或程式碼結尾沒有加上分號而導致的問題。
1 | ;(function(global, $) { ... } |
不使用 new 就可以建立物件
我們可以利用 return
一個 function constructor
的方式來達到這樣的效果,如下面程式碼中第 1 部分所示,而第 2 部分,才是我們真正的函數建構子。
1 | ;(function (global, $) { |
建立函數建構子的預設值
接著,我們要在函式裡面為 firstname
, lastname
和 language
來建立預設值
[筆記] JavaScript中coercion的實際使用–建立函式預設值(default value)
[筆記] 談談JavaScript中的”this”和它的bug
1 | Greetr.init = function (firstName, lastName, language) { |
ES6還可以這麼做
1 | Greetr.init = function (firstName = '', lastName = '', language = 'ch') { } |
為了避免 this
可能在後面使用時碰到一些問題,所以在第 1 部分的地方,我們用 var self = this
這樣的方法,來避免 this
在後續操作上可能會碰到的問題;在第 2 部分的地方,我們則是透過 JavaScript 中強制轉換coercion的特性,使用 OR operator ||
的方式來達到預設值的效果。
建立函數建構子的原型(prototype)
參考:JS的原型繼承(方法1) - 函數建構子 與「new」 該篇文章中的函數建構子和prototype的建立部分
1 | ;(function (global, $) { |
我們的函數建構子是 Greetr.init
,如果要設定相關方法,照理說應該要設定在Greetr.init.prototype
,但是為了讓程式碼更好閱讀,我們要將方法設置在 Greetr.prototype
內,如 /* 1 */
。
再來我們還必須讓 Greetr.init 建構子
所建立的物件實體 instance 可以參考到 Greetr.prototype
內的方法,我們可以使用/* 2 */
這行程式碼來達到目的。
使用 G$( ) 即可快速建立物件
就像在 jQuery 中,我們可以使用 jQuery()
或 $()
來選取DOM,在這裡,我們希望我們可以使用 Greetr()
或 G$()
這兩種方式來建立物件。
我們只需要加上這一行,就可以達到這樣的效果了。
1 | G$ = Greetr |
讓全域環境也可以取用
如果是上面的寫法,只有在這個IFFE內才能取用到 G$()
和 Greetr()
,因為就詞彙環境來說,全域物件裡並沒有這個變數。
1 | global.G$ = global.Greetr = Greetr |
加上Global
,是為了讓全域都可以使用這些功能 ,如此一來 G$()
和 Greetr()
也可以在全域環境下使用了。
測試
目前為止的 Greetr.js 程式碼如下,已經可以簡單使用了。
1 | ;(function(global, $){ |
試著在 app.js
,建立一個物件:
var a = G$('Dylan', 'Liu', 'EN')
結果