[書籍精讀]《基於MVC的JavaScript Web富應用開發》精讀筆記分享

寫在前面

  • 書籍介紹:這本書專一於講述如何構建「優雅又不失高水準」的JavaScript應用,包括軟件架構、模板引擎、框架和庫、同服務器的消息通訊等內容。
  • 個人簡評:比較老的一本書,引用的一些框架和庫如今已經不流行了,能夠大體翻看一下。內容主要講如何抽象js前端開發,讓代碼變得更清晰,具體採用的方法在js裏面實現class、MVC、module等抽象,對提升編程思惟幫助仍是挺大的。
  • !!福利:文末有pdf書籍、筆記思惟導圖、隨書代碼打包下載地址哦

《基於MVC的JavaScript Web富應用開發》_Alex MacCaw_李晶等.png

第1章 MVC和類

之初

  • 一個緣由是早期的JavaScript實現很是糟糕,有不少bug;另外一個緣由是由於其名字帶有「Java」前綴,讓人覺得它和Java有關係
  • 真正的緣由在於大多數開發者接觸使用JavaScript的方式

增長結構

  • 構建大型的JavaScript應用的祕訣是不要構建大型JavaScript應用。你應當把你的應用解耦成一系列相互平等且獨立的部分
  • 本書提倡使用MVC模式,這是一種久經考驗的搭建應用的方式,能夠確保應用的可維護性和可擴展性

什麼是MVC

  • MVC是一種設計模式,它將應用劃分爲3個部分:數據(模型)、展示層(視圖)和用戶交互層(控制器
  • 一個事件的發生是這樣的過程:1.用戶和應用產生交互;2.控制器的事件處理器被觸發;3.控制器從模型中請求數據,並將其交給視圖;4.視圖將數據呈現給用戶;

模型

  • 模型用來存放應用的全部數據對象
  • 模型沒必要知曉視圖和控制器的細節,模型只需包含數據及直接和這些數據相關的邏輯。任何事件處理代碼、視圖模板,以及那些和模型無關的邏輯都應當隔離在模型以外

視圖

  • 視圖層呈現給用戶的,用戶與之產生交互。在JavaScript應用中,視圖大都是由HTML、CSS和JavaScript模板組成的。除了模板中簡單的條件語句以外,視圖不該當包含任何其餘邏輯

控制器

  • 控制器是模型和視圖之間的紐帶。控制器從視圖得到事件和輸入,對它們進行處理(極可能包含模型),並相應的更新視圖

向模塊化進軍 建立類

  • 有必要強調一下:JavaScript是基於原型的編程語言,並無包含內置類的實現。但經過JavaScript能夠輕易的模擬出經典的類
  • JavaScript中並無真正的類,但JavaScript中有構造函數和new運算符。構造函數用來給實例對象初始化屬性和值。任何JavaScript函數均可以用作構造函數,構造函數必須使用new運算符做爲前綴來建立新的實例
  • new 運算符改變了函數的執行上下文,同時改變了return語句的行爲
  • 當使用new關鍵字來調用構造函數時,執行上下文從全局對象(window)變成一個空的上下文,這個上下文表明瞭新生成的實例

基於原型的類繼承

  • JavaScript是基於原型的編程語言,原型用來區別類和實例
  • 當你讀取一個對象的屬性時,JavaScript首先會在本地對象查找這個屬性,若是沒有找到,JavaScript開始在對象的原型中查找,若還未找到還會繼續查找原型的原型,直到查找到Object.prototype。若是找到這個屬性,則返回這個值,不然返回undefined

函數調用

  • 函數內上下文,如this的取值,取決於調用它的位置和方法
  • 其餘兩種方法能夠調用函數:apply()和call()。二者的區別在於傳入函數的參數的形式
  • 其餘編程語言不容許手動更換上下文也沒什麼很差。JavaScript中容許更換上下文是爲了共享狀態,尤爲是在事件回調中
  • 在新版本的JavaScript-ES5種一樣加入了bind()函數用以控制調用的做用域。bind()是基於函數進行調用的。用來確保函數是在指定的this值所在的上下文中調用的

添加私有方法

  • 不少開發者都習慣在私有屬性以前冠如下劃線前綴_。儘管本質上這並非私有屬性,但至少能一眼看出來他們就是私有屬性,所以它是私有API的組成部分
  • JavaScript的確支持不可變屬性,然而在主流瀏覽器中並未實現,咱們還沒辦法直接利用這個特性
  • 相反,咱們能夠利用JavaScript匿名函數建立私有做用域,這些私有做用域只能在內部訪問

第2章 事件和監聽

寫在前面

  • 在JavaScript誕生之初「事件」的實現並不標準
  • 儘管後來W3C對此做了標準化,但IE仍然堅持使用與W3C不兼容的事件模型,直到發佈的IE9才遵循標準化
  • jQuery和Prototype的類庫很好的處理了兼容性問題,對外提供了統一的API來實現事件

監聽事件

  • 綁定事件監聽的函數叫作addEventListener(),它有3個參數:type、listener及useCapture

事件順序

  • Netscape4支持事件捕捉(capturing),從頂層的父節點開始觸發事件,從外到內傳播
  • 微軟則支持事件冒泡(bubbling),從最內層的節點開始觸發事件,逐級冒泡直到頂層節點,從內向外傳播
  • W3C對此作了讓步,將對這兩種事件模型的支持都加入標準規範之中。根據W3C模型,事件首先被目標元素所捕捉,而後向上冒泡

取消事件

  • 一些類庫如jQuery還支持stopImmediatePropagation()函數,用來阻止後續全部的事件觸發-哪怕這些事件是註冊在同一個節點元素上的也不例外
  • 能夠經過調用event對象的preventDefault()函數來阻止默認行爲,一樣也能夠經過在回調中返回false來實現一樣的效果

事件庫

  • jQuery的API提供了bind()函數用來跨瀏覽器綁定事件監聽。在一個jQuery實例上調用此函數,傳入事件名稱和回調函數
  • 並非全部的瀏覽器都支持DOMContentLoaded,所以jQuery將它融入ready()函數,這個函數是兼容各個瀏覽器的

委託事件

  • 從事件冒泡時開始就發生了事件委託,咱們能夠直接給父元素綁定事件監聽,用來檢測在其子元素內發生的事件

自定義事件

  • 除了瀏覽器內置的事件以外,咱們也能夠觸發和綁定自定義事件
  • jQuery中可使用trigger()函數來觸發自定義事件

DOM無關事件

  • 事件本質上是和DOM無關的,所以能夠很容易的開發一個事件驅動的庫
  • 發佈/訂閱(Pub/Sub)是一種消息模式,它有兩個參與者:發佈者和訂閱者。發佈者向某個信道(channel)發佈一條消息,訂閱者綁定這個信道,當有消息發佈至信道時就會接受到一個通知
  • 發佈者和訂閱者的解耦可讓你的應用易於擴展,而沒必要引入額外的交叉依賴和耦合,從而提升了應用的可維護性,添加額外功能也很是容易

第3章 模型和數據

  • 傳統方式是經過頁面請求從數據庫獲取數據,用戶和頁面中的結果進行直接交互
  • 在複雜的JavaScript應用中作數據管理是很是困難的。前端並無請求/響應模型,也沒有辦法訪問服務器端的變量,甚者,遠程取回的數據只是臨時的保存在客戶端

MVC和命名空間

  • 在JavaScript中,咱們經過給對象添加屬性來管理一個命名空間,這個命名空間能夠是函數,也能夠是變量

構建對象關係映射(ORM)

  • 對象關係映射(Object-relational mapper,簡稱ORM)是在除了JavaScript之外的編程語言中常見的一種數據結構
  • 在JavaScript應用中,對象關係映射也是一種很是有用的技術,它能夠用作數據管理及用作模型
  • 原型繼承:Object.create()傳入一個對象,返回一個繼承了這個對象的新對象,能夠很容易的模擬出這個函數
  • 添加ORM屬性:jQuery.extend()只是代替for循環手動複製屬性的一種快捷方式
  • 持久化記錄:咱們須要一種保持記錄持久化的方法,即將引用保存至新建立的實例中以便任什麼時候候都能訪問它

增長ID支持

  • 技術的角度講,出於API的緣由,Javascript沒法友好正式的生成128位的GUID,它只能生成僞隨機數
  • 生成真正隨機的GUID是一個衆所周知的難題,操做系統使用MAC地址、鼠標位置、BIOS的校驗和、測量電信號的噪聲或者檢測放射性衰變來計算GUID,甚至用上了熔岩燈

裝載數據

  • 數據的預加載時一個重要的手段,這能讓應用的體驗更流暢、速度更快,用戶的等待時間也儘量壓縮到很短
  • 數據能夠直接嵌套顯示在初始頁面中,或者經過Ajax或JSONP的方式使用單獨的HTTP請求加載數據
  • 直接在初始頁面中嵌套數據會增長頁面體積,而並行加載會更快一些。Ajax和JSON一樣容許你將HTML頁面緩存住,而不是每次渲染都會動態發起請求
  • JSONP:原理是經過建立一個script標籤,所轄的外部文件包含一段JSON數據,數據是由服務器所返回的,做爲參數包裝在一個函數調用中。script標籤獲取腳本文件並不受跨域的限制,全部瀏覽器都支持這種技術

本地存儲數據

  • 在過去本地數據存儲一直都是瓶頸。唯一可用的方法就是使用cookies和相似Adobe Flash的插件
  • HTML5加入了對本地存儲的支持,並且主流瀏覽器都已經實現了本地存儲。和cookies不一樣,這些數據妥妥的存放在客戶端,且不會發給服務器。並且可存儲的數據量很是巨大,不一樣的瀏覽器額存儲上限有所不一樣,但至少都能爲每一個域名提供5M的存儲空間
  • 瀏覽器端所儲存的數據是以域名分隔開的,某個域中的腳本存儲的數據只能被這個域讀取

給ORM添加本地存儲

  • 頁面加載時從本地存儲中讀取數據,頁面關閉時將數據保存在本地存儲中,這的確是個好主意

第4章 控制器和狀態

寫在前面

  • JavaScript應用每每被限制在單頁面,這也意味着能夠將狀態保存在客戶端的內存中
  • 應當避免將狀態或數據保存在DOM中,由於根據滑坡理論,這會致使程序邏輯變得更加錯綜複雜且混亂不堪
  • 控制器是模塊化的且很是獨立
  • 理想狀態下不該該定義任何全局變量,而應當定義徹底解耦的功能組件

模塊模式

  • 模塊模式是用來封裝邏輯並避免全局空間污染的好方法。使用匿名函數能夠作到這一點,匿名函數也是JavaScript中被證實最優秀的特性之一

添加少許上下文

  • 使用局部上下文是一種架構模塊頗有用的方法,特別是當須要給事件註冊回調函數時

狀態機

  • 使用狀態機能夠輕鬆地管理不少控制器,根據須要顯示和隱藏視圖
  • 本質上講狀態機由兩部分組成:狀態和轉換器。它只有一個活動狀態,但也包括不少非活動狀態。當活動狀態之間相互切換時就會調用狀態轉換器

路由選擇

  • 咱們須要將應用的狀態反映在URL中,創建狀態和URL的某種對應關係,當應用的狀態發生改變時,URL也隨之改變,反之亦然

第5章 視圖和模板

寫在前面

  • 視圖是應用的接口,它們爲用戶提供視覺呈現並與用戶產生交互
  • 視圖是無邏輯的HTML片斷,由應用的控制器來管理,視圖處理事件回調及內嵌數據
  • 最經常使用的方法就是用Ajax,Ajax返回一個JSON對象,而後由應用的模型載入它。你沒必要在服務器端對HTML作預渲染操做,而是將渲染界面的操做全放在客戶端

動態渲染視圖

  • 經過JavaScript程序建立視圖有不少種方式,其中一種方式是使用document.createElement()建立DOM元素,設置它們的內容並將它們追加至頁面中。當須要重繪視圖時,只需將視圖清空並重復前面的過程
  • 我更推薦將靜態HTML包含在頁面中,在必要的時候顯示或隱藏。這會讓控制器中全部和視圖相關的代碼量降到最少,你也能夠根據須要更新元素的內容

模板

  • JavaScript模板的核心概念是,將包含模板變量的HTML片斷和JavaScript對象作合併,把模板變量替換爲對象中的屬性值
  • JavaScript中的模板類庫的實現原理和其餘語言沒什麼兩樣,好比PHP的Smarty,Ruby的ERB,以及Python的字符串格式化

綁定

  • 本質上講,綁定將視圖元素和JavaScript對象(一般是模型)掛接在一塊兒。當JavaScript對象發生改變時,視圖會根據新修改後的對象作實時更新
  • 綁定,意味着當記錄發生改變時你的控制器沒必要處理視圖的更新,由於這些更新都是在後臺自動完成的

第6章 依賴管理

  • JavaScript中缺失了不少計算機高級編程語言所應有的功能特性,其中一個重要的特性就是依賴管理和模塊系統
  • 依賴管理系統除了能解決實際的編程複雜度和可維護性的問題,還能解決性能方面的問題

CommonJS

  • Node.js提供了require()函數,用來加載外部資源文件,Node.js自有的模塊系統也使用這種方式來管理

模塊加載器

  • 目前最主要、應用最普遍的兩個模塊實現時Transport C和Transport D
  • Yabble
  • RequireJS

模塊的按需加載

  • Sprockets很是聰明,它會保證只加載庫文件一次,自動忽略以後的加載需求。相比於CommonJS模塊,Sprockets支持緩存和壓縮
  • Sprockets(包括全部的模塊包裝器)的中心思想是,全部的JavaScript文件都須要預處理,無論是在服務器端用程序做處理,仍是使用命令行工做做處理
  • LABjs

無交互行爲內容的閃爍(FUBC)

  • 用戶可能會看到頁面閃了一下,出現一部分沒有交互行爲的內容快速閃過(FUBC),好比在JavaScript執行以前會有一部分無樣式的頁面原始內容閃爍一下

第7章 使用文件

  • 以往,文件的訪問和操做都是基於桌面應用程序,在Web中操做文件必須藉助第三方插件技術,好比Adobe Flash
  • 在現代瀏覽器中,用戶能夠直接將文件拖拽進頁面中,粘貼格式化數據,或是實時查看上傳文件的進度

瀏覽器支持

  • 特性檢測:window.File && window.FileReader && window.FileList

獲取文件信息

  • HTML5的文件操做有必定的安全限制,主要的限制是只有被用戶選中的文件才能被訪問

文件輸入

  • 對於開發者來講,長期以來很讓人頭疼的是多文件上傳。過去開發者只能堆積不少文件輸入框或者依賴插件(如Flash)來實現多文件上傳。HTML5提供了multiple屬性來支持多文件

拖拽

  • 早在1999年,微軟的IE5就「設計」並實現了最原始的拖拽,自那時起後續的IE版本都支持拖拽。HTML5規範剛剛增長了拖拽的內容,如今Safari、Firefox和Chrome也都模仿IE的實現提供了拖拽支持

複製和粘貼

  • 除了將拖拽功能和桌面進行整合,有些瀏覽器還支持複製和粘貼
  • 複製粘貼使用了clipbordData,拖拽使用了dataTransfer

讀文件

  • 當你得到File的引用時,能夠用它來實例化一個FileReader對象,將文件內容讀入內存
  • FileReader中包含四個方法來讀取文件數據:readAsBinaryString、readAsDataURL、readAsText、readAsArrayBuffer
  • 二進制大文件和文件切割

自定義瀏覽器按鈕

  • 咱們每每但願點擊一個帶自定義樣式的「瀏覽」或「附件」按鈕來即刻打開瀏覽文件對話框
  • 文件輸入框並不提供打開瀏覽文件對話框的函數,並且Firefox的實現更詭異,當點擊文件輸入框時甚至沒法觸發自定義的click事件
  • hack技術,當將鼠標移動到按鈕上方時,在相同的位置放置一個透明的文件輸入框,尺寸和按鈕同樣。透明的文件輸入框能夠獲取任何點擊事件,並打開一個瀏覽文件的對話框

上傳文件

  • FormData實例用一種很是簡單的接口表示表單的內容。能夠直接經過抓取一個表單來建立FormData,或者在實例化對象時傳入已經存在的form元素

jQuery拖拽上傳

  • 實現一個可拖拽上傳文件的功能。須要幾個庫:jquery.js用來作底層庫,jquery.ui.js用來構建進度條,jquery.drop.js用來提供抽象的拖拽API,以及jquery.upload.js用來做Ajax上傳

第8章 實時Web

實時Web的發展歷史

  • 傳統的Web是基於HTTP的請求/響應模型的:客戶端請求一個新頁面,服務器將內容發送到客戶端,客戶端再請求另一個頁面時又要從新發送請求
  • 若是服務器有更多數據須要推送到客戶端,在頁面加載完成後是沒法直接將數據從服務器發送給客戶端的
  • 最簡單(暴力)的方案是用輪詢:每隔一段時間都會向服務器請求新數據,這讓用戶感受應用是實時的
  • 後面隨着Comet技術的提出,又出現了不少更高級的解決方案。這些技術方案包括永久幀(forever frame)、XHR流(xhr-multipart)、htmlfile以及長輪詢
  • 長輪詢是指,客戶端發起一個到服務器的XHR鏈接,這個鏈接永不關閉,對客戶端來講鏈接始終是掛起狀態。當服務器有新數據時,就會及時地將響應發送給客戶端,接着再將鏈接關閉。而後重複整個過程,經過這種方式就實現了「服務器推」(server push)
  • 如今HTML5規範爲咱們準備了一個替代方案。鑑於大部分瀏覽器還未實現HTML5的WebSocket,現行最好的辦法仍然是使用Comet

WebSocket

  • WebSocket是HTML5規範的一部分,提供基於TCP的雙向的、全雙工的socket鏈接。這意味着服務器能夠將數據推送給客戶端,而不須要開發者求助於長輪詢或插件來實現,這是一個很大的進度
  • 爲了更好更成功的使用WebSocket,這裏給出一些步驟
  • 幸運的是,在不少語言中都實現了對WebSocket的支持,好比Ruby、Python和Java
  • Node.js和Socket.IO

實時架構

  • 實時架構是基於事件驅動的(event-driven)。事件每每是由用戶交互觸發的:用戶修改了數據記錄,事件就會傳播給系統,直到數據推送給已經創建鏈接的客戶端並更新數據
  • 如何向特定用戶發送通知?最佳方法是使用發佈/訂閱模式:客戶端訂閱某個特定的信道,服務器向這個信道發佈消息。每一個用戶訂閱唯一的信道。信道包含一個ID,多是用戶在數據庫中存放的ID。而後,服務器只需向這個唯一的信道發佈消息便可,這樣就能夠作到將通知發送給特定的用戶

感知速度

  • 速度是UI設計最重要也是最易忽略的問題,速度對用戶體驗(UX)的影響很是大,並直接影響網站的收益
  • Web應用中最耗時的部分就是新數據的加載。最明智的作法是在用戶請求數據以前預測用戶的行爲並預加載數據,這一點很是重要

第13章 JavaScriptMVC類庫

  • JavaScriptMVC(JMVC)是一個基於jQuery的開源JavaScript框架。它基本上就是一個完整的前端開發框架,將一些實用的測試工具、依賴關係管理、文檔和許多很是有用的jQuery插件都打包在一塊兒了
  • JavaScriptMVC的$.Class(基於JavaScript的類系統)、$.Model(傳統的模型層)、$.View(客戶端模板系統)、$.Controller(jQuery的widget工廠)

模型

  • JavaScriptMVC的模型和它的插件提供了不少組織模型數據的工具,如校驗、關聯、列表等。但核心功能集中在服務封裝、類型轉換和事件上

在視圖中使用客戶端模板

  • $.View是一個模板接口,使用模板來下降複雜度,提供以下支持

寫在後面

相關文章
相關標籤/搜索