2016年7月19日 星期二

[筆記] 親手打造屬於你自己的 JavaScript Framework/Library(上)




在上一篇[筆記] 跟著JQuery原始碼一起學習程式設計中,我們從 jQuery 的原始碼中,學到了一些建立 framework 的概念和技巧,在這篇筆記中,我們就要來試著打造我們自己的 framework 啦。

Requirement


當我們在打造一個 framework 時,事先規劃好這個 framework 要具備哪些功能是很重要的,而不是一股腦的就打開程式編輯器開始寫,所以我們來規劃一些這個 framework 要具備哪些功能吧!

在這系列的課程,我們大部分都是用 greeting(打招呼) 來當作程式撰寫的例子,在這堂課中也不例外,我們要來打造一個和 greeting 有關的 framework ,我們把它稱做 "greetr"。

我們的需求是這樣的:

  1. 當我們告訴它我們的姓(lastname)名(firstname)還有選擇的語言(language)時,它可以用正式(formal)和非正式(informal)的方式和我們打招呼。
  2. 支援英文(English)和繁體中文(zh_tw)兩種語言。
  3. 是一個可重複使用的 library/framework,也就是說,每一個安裝此 framework 的人可以直接使用,不會和它原本程式碼有所衝突。
  4. 和 jQuery 只需要輸入 "$( )" 一樣,我們可以使用 "G$( )" 來建立物件。
  5. 支援 jQuery ,可以把 greetr 產生的訊息直接顯示於HTML中。

HTML部分


在HTML中,我們總共會匯入三支js檔,第一支是 jQuery,因為在我們的 framework 中會使用到一些 jQuery 的功能;第二支是 greetr.js 這支就是我們寫 framework 的地方;最後一支是 app.js ,這一支則是我們用來應用我們所寫的 framework 的地方。


  <!doctype html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>Untitled Document</title>
  </head>
  <body>
    <script src="jquery-3.0.0.js"></script>
    <script src="greetr.js"></script>
    <script src="app.js"></script>
  </body>
  </html>



讓程式碼位於安全的位置

現在,我們可以開始在 greetr.js 中開始編輯我們的 library 了。

首先,為了避免我們所寫的 framework 被外層的變數所影響,我們要善用 IIFEs ,也就是將我們所寫的 library 放到 IIFEs 裡面。
同時,因為我們要讓我們的 framework 能夠影響到 global 的內容,同時還要支援 jQuery ,因此在參數的地方,我們會帶入 global 和 $ 。



不需要使用 new 就可以建立物件


在上堂筆記中看過 jQuery 的架構後,我們希望可以將學到的東西應用到我們的 framework 中,也就是說,我們希望可以輸入 var g = G$(firstname, lastname, language) 如此就能建立出一個新的物件而不用用到 new 這個關鍵字,我們可以怎麼做呢?
從上一堂課的筆記中,我們知道我們可以利用 return 一個 function constructor 的方式來達到這樣的效果,如圖中第 1 部分所示,而圖中的第 2 部分,才是我們真正建立函式的地方。

第 1 部分之所以可以寫在第 2 部分前面,是因為第 1 部份要在我們執行 Greetr 時,才會真的加以執行


建立函式裡面的預設值


接著,我們要在函式裡面為 firstname, lastname和 language 來建立預設值,還記得我們可以怎麼做嗎?

首先,因為我們這是一個 function constructor ,為了避免 this 可能在後面使用時碰到一些問題,所以在第 1 部分的地方,我們用 var self = this 這樣的方法,來避免 this 在後續操作上可能會碰到的問題;在第 2 部分的地方,我們則是透過 JavaScript 中強制轉換(coercion)的特性,使用 OR operator  || 的方式來達到預設值的效果。


建立建構子的原型(prototype)


接著,我們要來建立這個函式建構子(function construct)的原型了,還記得原型(prototype)嗎?
為了程式容易閱讀,我想要將這個建構子的原型,用 Greetr.prototype 來表示,於是就如下圖第 1 部分所示。

可是,我們知道,我們現在函式建構子的名稱是 Greetr.init ,所以這個建構子的原型名稱其實是 Greetr.init.prototype 才對,因此,如同 jQuery 中所使用的方式,我們可以在第 2 部分的地方寫上 Greetr.inti.prototype = Greetr.prototype ,如此,我們就可以直接在 Greetr.prototype 中撰寫程式碼了。


使用 G$( ) 即可建立物件


就像在 jQuery 中,我們可以使用 jQuery( ) 或 $( ) 來建立物件,在這裡,我們希望我們可以使用 Greetr( ) 或 G$( ) 這兩種方式都可以建立物件,記得在 jQuery 中是怎麼做到的嗎?

我們只需要加上這一行,就可以達到這樣的效果了。


到目前為止...


到目前為止,我們的框架 greetr.js 長這樣子,而且它已經可以簡單使用了。


  (function(global, $){
  
    var Greetr = function(firstname, lastname, language){
      return new Greetr.init(firstname, lastname, language);
    }
  
    Greetr.prototype = {}
  
    Greetr.init = function(firstname, lastname, language){
  
      var self = this;
      self.firstname = firstname || '';
      self.lastname = lastname || '';
      self.language = language || 'zh_tw';
  
    }
  
    Greetr.init.prototype = Greetr.prototype;
  
    global.Greetr = global.G$ = Greetr;
  
  })(window, jQuery)


如果我們在 app.js 當中,輸入以下內容:


var g = G$('PJ', 'CHEN');
console.log(g);


已經可以成功獲得一個物件了!






→回到此系列文章目錄



Share:

0 意見:

張貼留言