[书籍精读]《基于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是一个模板接口,使用模板来下降复杂度,提供以下支持

写在后面

相关文章
相关标签/搜索