写在前面书籍介绍:本书着重讲述如何构建“优雅而高级”的JavaScript应用程序,包括软件架构、模板引擎、框架和库,与服务器的消息通信等我的简评:比较老的书了,引用的一些框架和库已经不流行了,可以看看。内容主要讲如何抽象js前端开发,让代码更清晰。具体使用的方法是在js中实现class、MVC、module等抽象,对于提高编程思维还是挺有帮助的。!!福利:文末有pdf书籍,笔记思维导图,以及随书代码包下载地址。阅读【书籍精读】系列所有文章,请移步:推荐合集-JavaScript书籍精读笔记系列导航第1章MVC与classes的开端一个原因是早期的JavaScript实现很烂,bug多;另一个原因是因为它的名字有一个“Java”前缀,让人觉得它与Java有关。真正的原因是大多数开发人员处理JavaScript的方式增加了结构。构建大型JavaScript应用程序的秘诀在于不构建大型JavaScript应用程序。您应该将您的应用程序解耦为一系列相等且独立的部分本书提倡使用MVC模式,这是一种久经考验的构建应用程序的方式,可确保可维护性和可扩展性什么是MVCMVC它是一种将应用程序划分的设计模式分为三部分:数据(模型)、表现层(视图)和用户交互层(控制器)。一个事件的发生是这样一个过程:1.用户与应用进行交互;2.控制器的事件处理器被触发;3、controller向model请求数据,交给view;4、视图将数据呈现给用户;模型模型用于存储应用程序的所有数据对象。模型不需要知道视图与控制器的细节一样,模型只需要包含与这些数据直接相关的数据和逻辑。任何与模型无关的事件处理代码、视图模板和逻辑都应该与模型隔离,并由视图层呈现给用户。用户与之交互。在JavaScript应用程序中,视图主要由HTML、CSS和JavaScript模板组成。除了模板中的简单条件语句外,视图不应包含任何其他逻辑。控制器是介于模型和视图之间的纽带。控制器从视图获取事件和输入,处理它们(可能包括模型),并相应地更新视图以创建用于模块化的类。需要强调的是,JavaScript是一种基于原型的编程语言,不包含内置类的实现。但是通过JavaScript可以很容易模拟出经典JavaScript中没有真正的类,但是JavaScript中有构造函数和new运算符。构造函数用于初始化实例对象的属性和值。任何JavaScript函数都可以用作构造函数。构造函数必须以new运算符为前缀才能创建新实例。new运算符改变了函数的执行上下文,也改变了使用new关键字调用构造函数时return语句的行为。当执行上下文从全局对象(窗口)变为空上下文时,这个上下文代表新生成的实例。基于原型的类继承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()函数来阻止所有后续的事件触发——即使这些事件被注册在同一个节点元素上也不例外。您可以通过调用事件对象的preventDefault()函数来阻止默认行为,也可以通过在回调中返回false来达到相同的效果。事件库jQuery的API提供了跨浏览器绑定的bind()函数。设置事件监听。在jQuery实例上调用此函数,并传入事件名称和回调函数。并不是所有的浏览器都支持DOMContentLoaded,所以jQuery将其集成到ready()函数中,兼容各个浏览器的委托事件从事件冒泡开始事件委托,我们可以直接在父元素上绑定事件监听器来检测事件出现在它的子元素中。除了浏览器内置事件,我们还可以触发和绑定自定义事件。定义事件jQuery中可以使用trigger()函数来触发自定义事件DOM独立事件事件本质上独立于DOM,因此很容易开发事件驱动库。发布/订阅(Pub/Sub)是一种消息模式,它有两个参与者:发布者和订阅者。发布者向通道发布消息,订阅者绑定到通道。当消息发布到频道时,它会收到通知。发布者和订阅者的解耦可以让你的应用易于扩展,并且不需要引入额外的交叉依赖和耦合,提高了应用的可维护性,添加额外的功能也非常容易第3章模型而Data传统的方式是通过页面请求从数据库中获取数据,用户直接在页面中与结果进行交互,在复杂的JavaScript应用中进行数据管理是非常困难的。前端没有请求/响应模型,无法访问服务器端变量。更重要的是,远程检索的数据只是暂时存储在客户端MVC和命名空间中。在JavaScript中,我们通过给对象添加属性来管理一个命名空间,这个命名空间可以是一个函数,也可以是一个变量来构建一个对象关系映射(ORM)对象关系映射器(简称ORM)是编程语言中常见的数据结构除了JavaScript。在JavaScript应用中,对象关系映射也是一个非常有用的技术,它可以用于数据管理和模型继承:Object.create()传入一个对象并返回一个继承该对象的新对象,可以很容易地模拟出这个函数来添加ORM属性:jQuery.extend()只是一个快捷方式来代替在for循环中手动复制属性从添加ID支持技术的角度来看,Javascript无法以友好和正式的方式生成128位GUID由于API原因。它只能生成伪随机数。生成真正随机的GUID是一个众所周知的问题。操作系统使用MAC地址、鼠标位置、BIOS的校验和,测量电信号噪声或检测放射性衰变来计算GUID,甚至使用熔岩灯加载数据。数据预加载是一个重要的手段,它可以让应用体验更流畅、更快捷,尽可能缩短用户的等待时间。数据可以直接嵌套显示在初始页面,也可以直接嵌套在初始页面,使用单独的HTTP请求通过Ajax或JSONP加载数据。数据会增加页面大小,并行加载会更快。Ajax和JSON也允许你缓存HTML页面,而不是每次渲染时都动态请求JSONP:原理是创建一个script标签,其管辖的外部文件包含一段JSON数据,由服务器返回as参数包装在函数调用中。脚本标签不受跨域访问脚本文件的限制。所有浏览器都支持这项技术。过去,本地数据存储一直是瓶颈。唯一可用的方法是使用cookie和Adob??eFlash等插件。HTML5增加了对本地存储的支持,各大浏览器都已经实现了本地存储。与cookie不同的是,这些数据被妥善存储在客户端,不会发送到服务器端。而且,可以存储的数据量是巨大的。不同的浏览器有不同的存储限制,但至少可以为每个域名提供5M的存储空间。存储在浏览器中的数据以域名分隔。域中脚本存储的数据只能被本域读取。将本地存储添加到ORM。页面加载时从本地存储中读取数据,页面关闭时将数据保存在本地存储中。这确实是个好主意。第4章控制JavaScript应用程序通常仅限于单个页面,这也意味着状态可以保存在客户端的内存中。应避免在DOM中保留状态或数据,因为根据滑坡理论,这会导致程序逻辑发生变化。控制器是模块化的,非常独立。理想情况下,不应定义全局变量,而应定义完全解耦的功能组件。模块模式是封装逻辑和避免全局空间污染的好方法。方法。这可以使用匿名函数来完成,这也是JavaScript中公认的最佳特性之一。添加少量上下文使用本地上下文是构建模块的一种非常有用的方法,尤其是当您需要为事件注册回调函数时。状态机许多控制器可以使用状态机轻松管理,根据需要显示和隐藏视图本质上,状态机由两部分组成:状态和转换。它只有一个活动状态,但它也包括许多非活动状态。当活动状态相互切换时,状态转换器将被调用。路由选择我们需要在URL中体现应用的状态,并在状态和URL之间建立一定的对应关系。当应用程序的状态发生变化时,URL也会发生变化,反之亦然第5章视图和模板写在前端视图是应用程序的界面,它们为用户提供视觉呈现并与用户进行交互而嵌入数据最常见的方式是使用Ajax,Ajax返回一个JSON对象,然后由应用程序的模型加载。你不必在服务器端预先渲染HTML,而是将渲染界面的所有操作都放在客户端动态渲染视图通过JavaScript程序创建视图的方法有很多种,其中一种是使用document.createElement()创建DOM元素,设置它们的内容并将它们附加到页面。当需要重绘视图时,只需清除视图并重复前面的过程即可。我更喜欢在页面中包含静态HTML,在必要时显示或隐藏。这将最小化控制器中所有与视图相关的代码,您还可以根据需要更新元素的内容模板。替换为对象中的属性值JavaScript中模板类库的实现原理与其他语言无异,如PHP的Smarty、Ruby的ERB、Python的字符串格式绑定。本质上,绑定将视图元素和JavaScript对象(通常是模型)连接在一起。当JavaScript对象发生变化时,视图会根据新修改的对象实时更新绑定,这意味着当记录发生变化时你的控制器不必处理视图的更新,因为这些更新是在自动完成的的背景。ChapterDependencyManagementJavaScript缺少许多在高级计算机编程语言中应该具备的功能特性。重要的特性之一是依赖管理和模块系统。除了解决实际的编程复杂度和可维护性问题,依赖管理系统还可以解决性能问题CommonJSNode.js提供了require()函数来加载外部资源文件。Node.js自己的模块系统也使用这种方法来管理两个最重要和广泛使用的模块加载器。模块实现时,TransportC和TransportDYabbleRequireJS模块的按需加载非常智能。它将保证库文件只加载一次,自动忽略后续的加载要求。与CommonJS模块相比,Sprockets支持缓存和压缩。Sprockets(包括所有模块包装器)的中心思想是所有JavaScript文件都需要进行预处理,无论它们是在服务器端以编程方式处理还是使用命令行作业。处理LABjs非交互内容闪烁(FUBC)用户可能会看到页面闪烁一会,有些非交互内容闪烁很快(FUBC),比如页面中一些无样式的原始内容在JavaScript执行前闪烁执行阅读第7章使用文件过去,文件访问和操作基于桌面应用程序。要在Web上操作文件,必须使用第三方插件技术,例如Adob??eFlash。在现代浏览器中,用户可以直接将文件拖放到页面中,粘贴格式化数据,或者实时查看上传文件的进度。浏览器支持特性检测:window.File&&window.FileReader&&window.FileList获取文件信息HTML5文件操作有一定的安全限制。主要限制是只能访问用户选择的文件。文件输入对于开发者来说,上传多个文件一直是个头疼的问题。以往,开发者只能积累很多文件输入框,或者依靠插件(如Flash)上传多个文件。HTML5提供了multiple属性来支持多文件拖放。早在1999年,微软的IE5就“设计”并实现了最原始的拖放功能。此后,后续的IE版本都支持了拖放。HTML5规范刚刚加入了拖放内容,现在Safari、Firefox、Chrome除了集成拖放功能外,也模仿IE的实现,为复制粘贴提供拖放支持与桌面一样,一些浏览器也支持复制和粘贴使用剪贴板数据,拖放和使用数据传输来读取文件。当您获得对File的引用时,您可以使用它来实例化一个FileReader对象并将文件内容读入内存。FileReader包含四种读取文件数据的方法:readAsBinaryString、readAsDataURL、readAsText、readAsArrayBuffer大型二进制文件和文件切割自定义浏览器按钮我们经常希望点击一个自定义样式的“浏览”或“附件”按钮立即打开浏览文件对话框文件输入框并没有提供打开浏览文件对话框的功能,Firefox的实现就更奇葩了。当点击文件输入框时,甚至无法触发自定义点击事件hack技术。当鼠标移到按钮上时,在同一位置放置一个透明的文件输入框,大小与按钮相同。透明文件输入框可以获取任意点击事件,打开对话框浏览文件。上传文件。FormData实例使用一个非常简单的接口来表示表单的内容。可以通过抓取表单直接创建FormData,也可以在实例化对象时传入已有的表单元素jQuery拖拽上传,实现拖拽文件上传功能。需要几个库:jquery.js作为底层库,jquery.ui.js用于构建进度条,jquery.drop.js用于提供抽象的拖放API,jquery.upload.js是用于Ajax上传Chapter8Historyofthereal-timeWeb实时Web的发展历史传统的Web是基于HTTP的请求/响应模型:客户端请求一个新的页面,服务器端将内容发送给客户端,客户端在请求另一个页面时重新发送内容Request如果服务端有更多的数据要推送给客户端,页面加载完成后,不可能直接从服务端向客户端发送数据。最简单(暴力)的方案是使用轮询:请求新数据,让用户感觉应用是实时的。后来,随着Comet技术的引入,出现了很多更先进的解决方案。这些技术方案包括永久帧(foreverframe)、XHR流(xhr-multipart)、htmlfile和长轮询长轮询是指客户端向服务器发起一个XHR连接,这个连接永远不会关闭。表示连接始终处于挂起状态。当服务端有新数据时,会及时向客户端发送响应,然后关闭连接。然后重复整个过程,以这种方式实现“服务器推送”(serverpush)现在HTML5规范已经为我们准备了一个备选方案。由于大部分浏览器还没有实现HTML5WebSocket,目前最好的方式还是使用CometWebSocket。WebSocket是HTML5规范的一部分,提供基于TCP的双向、全双工套接字连接。这意味着服务器可以将数据推送到客户端,而无需开发人员诉诸长轮询或插件来这样做,这是向前迈出的一大步。为了更好、更成功地使用WebSocket,这里有一些步骤。幸运的是,对WebSocket的支持在很多语言中都有实现,例如Ruby、Python,以及JavaNode.js和Socket.IO实时架构实时架构是基于事件驱动(event-driven)的。事件通常由用户交互触发:用户修改数据记录,事件传播到系统,直到数据被推送到连接的客户端并更新。如何向特定用户发送通知?最好的方法是使用发布/订阅模式:客户端订阅一个特定的频道,服务器向这个频道发布消息。每个用户订阅一个唯一的频道。该频道包含一个ID,可能是存储在数据库中的用户ID。然后,服务器只需要向这个唯一的通道发布消息,就可以将通知发送给特定的用户。感知速度是UI设计中最重要也最容易被忽视的问题。速度对用户体验(UX)的影响非常大,直接影响网站的收入。Web应用程序最耗时的部分是加载新数据。最明智的做法是在用户请求数据之前预测用户的行为并预加载数据,这一点非常重要第13章JavaScriptMVC类库JavaScriptMVC(JMVC)是一个基于jQuery的开源JavaScript框架。它基本上是一个完整的前端开发框架,将一些实用的测试工具、依赖管理、文档和许多非常有用的jQuery插件打包在一起。JavaScriptMVC的$.Class(基于JavaScript的类系统),$.Model(传统模型层)、$.View(客户端模板系统)、$.Controller(jQuerywidgetfactory)模型JavaScriptMVC模型及其插件提供了很多组织模型数据的工具,如验证、关联、列表等.但核心功能集中在服务封装、类型转换和事件上。使用客户端模板$.View在视图中是一个模板接口,它使用模板来降低复杂性,并提供以下支持。书码包下载地址:https://pan.baidu.com/s/1JtxTu1QLMf5wk4k7d_Vmkg(提取码:9nex)纸质书京东购买地址:https://u.jd.com/JjOIhO(推荐使用纸质书toLearning)为了方便手机查看,我会陆续把这些笔记发到公众号“拍三拍四”。可以扫描二维码关注,欢迎关注。
