JavaScript代码组织结构良好的5个特点
JavaScript代码组织结构良好的5个特点,随着JavaScript项目的成长,如果你不小心处理的话,他们往往会变得难以管理。我们发现自己常常陷入的一些问题: 当在创建新的页面时发现,很难重用或测试之前写的代码。
当我们更深处地研究这些问题,我们发现根本原因是无效的依赖管理造成的。比如,脚本A依赖脚本B,并且脚本B又依赖脚本C,当C没有被正确引入时,整个依赖链就无法正常工作了。
为了解决这个问题,我们已经采取了异步模块定义(AMD)的模式,并引入require.js到我们的技术堆栈。经过对AMD的进一步探索,我们已经基本确定,组织严密的JavaScript一般都呈现以下五个特点:
始终声明我们的依赖 为第三方代码库添加shim(垫片) 定义跟调用应该分离 依赖应该异步加载 模块不应依赖全局变量
让我们详细讨论一下。
始终声明我们的依赖
我们最常碰到了的一个问题是,我们会经常忽略那些会被确定加载的依赖项。举例来说,如果我们创建了一个jQuery插件,一般认为没有必要申报jQuery的依赖,因为它在大多数页面都是默认装载的。虽然这似乎适用于大多数的网页,但当我们试图进行单元测试或在一个全新的页面加载时,它就变成一个问题。
始终声明我们的依赖,我们就消除了JavaScript中90%的问题。可重用的代码变得更可靠,单元测试的数量增加了4倍也是一个因素。
为第三方代码库添加shim(垫片)
在管理JavaScript依赖时经常碰到的一个有趣问题是,较旧的第三方库可能无法和您的依赖关系管理系统配合工作。例如,你们内部使用了jQuery的一个很酷的插件,但它对require.js一无所知。这会成为一个问题,因为第一个特点,我们来添加对这个插件的引用。
解决的办法是通过依赖管理工具为这个插件制作一个垫片。在require.js中,这可以很容易地通过配置来完成:
var require = {
- <p><font size="3"> "shim": {</font></p>
- <p><font size="3"> "lib/cool-plugin": {</font></p>
- <p><font size="3"> "deps": ["lib/jquery"]</font></p>
- <p><font size="3"> }</font></p>
- <p><font size="3"> }</font></p>
- <p><font size="3"> }</font></p>
有了这个简单的配置,每一个加载 lib/cool-plugin.js 的脚本都会自动加载jQuery。将有助于满足所有相关性.
最终的结果是代码更容易测试和重用,因为你总是有一个require()来调用所需的功能。
定义跟调用应该分离
这是限制JavaScript代码的可重用性和可测试性的一个常见问题。问题表现在一个单一的文件即定义了一个类/函数又调用了它。考虑下面的代码:
## js/User.js
- <p><font size="3"> define(functino(require) {</font></p>
- <p><font size="3"> var User = function(name, greeter) {</font></p>
- <p><font size="3"> this.name = name;</font></p>
- <p><font size="3"> this.greeter = greeter;</font></p>
- <p><font size="3"> };</font></p>
- <p><font size="3"> User.prototype.sayHello = function() {</font></p>
- <p><font size="3"> this.greeter("Hello, " + this.name);</font></p>
- <p><font size="3"> };</font></p>
- <p><font size="3"> var user = new User('Alice', window.alert);</font></p>
- <p><font size="3"> user.sayHello();</font></p>
- <p><font size="3"> });</font></p>
在这个例子中,一个单一的文件即定义了User类又调用它。这将很难重用这个代码,因为只要加载这个脚本就会出现alert。同样greeter这个非常难以测试。
解决的办法是保持定义和执行的分离。这有助于确保可重用性和可测性:
## js/User.js
- <p><font size="3"> define(functino(require) {</font></p>
- <p><font size="3"> var User = function(name, greeter) {</font></p>
- <p><font size="3"> this.name = name;</font></p>
- <p><font size="3"> this.greeter = greeter;</font></p>
- <p><font size="3"> };</font></p>
- <p><font size="3"> User.prototype.sayHello = function() {</font></p>
- <p><font size="3"> this.greeter("Hello, " + this.name);</font></p>
- <p><font size="3"> };</font></p>
- <p><font size="3"> return User;</font></p>
- <p><font size="3"> });</font></p>
- <p><font size="3"> ## js/my-page.js</font></p>
- <p><font size="3"> define(functino(require) {</font></p>
- <p><font size="3"> var User = require('js/User');</font></p>
- <p><font size="3"> var user = new User('Alice', window.alert);</font></p>
- <p><font size="3"> user.sayHello();</font></p>
- <p><font size="3"> });</font></p>
这种变化,User类可以安全地在许多脚本中重用。
依赖应该异步加载
因为试图同步加载脚本会导致浏览器锁死,这是非常重要的,你的脚本和你的模块应该使用异步加载机制。 Require.js在默认情况下,所有异步加载你的模块,只有所有的的依赖都加载完以后才会执行你的模块代码的函数。
通过使用一个闭包,我们可以进一步利用“use strict”的好处。
模块不应依赖全局变量
为了进一步加强我们的JavaScript代码库,我们已经(几乎)完全消灭了全局变量(除了由require.js提供的全局变量,如require()和define())。全局变量是臭名昭著的潜在的进入模块的“隐藏的依赖关系”,它会使代码很难重用或测试。
Require.js也让我们转换第三方全局变量,require() - 通过垫补功能能模块。在这个例子中,lib/calculator 创建一个全局的计算器对象,这个库是被require化的。
var require = {
- <p><font size="3"> "shim" : {</font></p>
- <p><font size="3"> "lib/calculator": {</font></p>
- <p><font size="3"> "export": "Calc"</font></p>
- <p><font size="3"> }</font></p>
- <p><font size="3"> }</font></p>
- <p><font size="3"> }</font></p>
JavaScript代码组织结构良好的5个特点的更多相关文章
- web开发中,前端javascript代码的组织结构
网页包含三个层次: 结构(HTML) 表现(CSS) 行为(javascript) web标准中,三者要分离,网页源代码由三部分组成:.html文件..css文件和.js文件.就是说html文件中不应 ...
- javascript代码 调试方法
你的代码可能包含语法错误,逻辑错误,如果没有调试工具,这些错误比较难于发现. 通常,如果 JavaScript 出现错误,是不会有提示信息,这样你就无法找到代码错误的位置. 在程序代码中寻找错误叫做代 ...
- 7个高性能JavaScript代码高亮插件
本文由码农网 – 小峰原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 对于喜欢写技术博客的同学来说,一定对代码高亮组件非常熟悉.一款优秀的JavaScript代码高亮插件,将会帮助你渲染 ...
- JavaScript代码段整理笔记系列(二)
上篇介绍了15个常用代码段,本篇将把剩余的15个补齐,希望对大家有所帮助!!! 16.检测Shift.Alt.Ctrl键: event.shiftKey; //检测Shift event.altKey ...
- JavaScript代码段整理笔记系列(一)
30段JavaScript代码——上篇 1.如何区分IE及非IE浏览器: if(!+[1,]){ //IE 11 不支持 alert("这是 IE 浏览器"): }else{ al ...
- 如何让你的JavaScript代码更加语义化
语义化这个词在 HTML 中用的比较多,即根据内容的结构化选择合适的标签.其作用不容小觑: 赋予标签含义,让代码结构更加清晰,虽然我们可以在标签上添加 class 来标识,但这种通过属性来表示本体的形 ...
- 推荐15个最好用的 JavaScript 代码压缩工具
JavaScript 代码压缩是指去除源代码里的所有不必要的字符,而不改变其功能的过程.这些不必要的字符通常包括空格字符,换行字符,注释以及块分隔符等用来增加可读性的代码,但并不需要它来执行. 在这篇 ...
- 新书《编写可测试的JavaScript代码 》出版,感谢支持
本书介绍 JavaScript专业开发人员必须具备的一个技能是能够编写可测试的代码.不管是创建新应用程序,还是重写遗留代码,本书都将向你展示如何为客户端和服务器编写和维护可测试的JavaScript代 ...
- FineUI(专业版)实现百变通知框(无JavaScript代码)!
博客园已经越来越不公正了,居然说我这篇文章没有实质的内容!! 我其实真的想问哪些通篇几十个字,没任何代码和技术分享,嚷嚷着送书的文章的就能雄霸博客园首页几天,我这篇文章偏偏就为管理员所容不下. 其实我 ...
随机推荐
- 精读《useEffect 完全指南》
1. 引言 工具型文章要跳读,而文学经典就要反复研读.如果说 React 0.14 版本带来的各种生命周期可以类比到工具型文章,那么 16.7 带来的 Hooks 就要像文学经典一样反复研读. Hoo ...
- 设计模式总结篇系列:装饰器模式(Decorator)
在面向对象设计过程中,经常会遇到需要对现有的类的功能进行扩展,通常我们可以采用继承的方式.例如老罗最近在做手机,一开始需要定义手机所应具有的功能: interface Phone{ public vo ...
- J2EE规范总结
概述 J2ee是我们步入java学习的一个開始.它将开启这趟奇幻之旅,Java是一种简单的,跨平台的,面向对象的,分布式的.解释的.健壮的安全的.结构的中立的,可移植的.性能非常优异的多线程的,动态的 ...
- Linux平台运行jmeter
这篇博客介绍 jmeter 在 Linux 环境进行压测,大致流程是 在 window上编辑好测试脚本,然后拷贝到 Linux上运行,再把 Linux上的运行结果拿到 windows 的 jmeter ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(1)- 源文件(.c/.h/.s)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的source文件. 众所周知,嵌入式开发属于偏底层的开发,主要编程语言是C和汇编.所以本文要讲的source文件主要指的就是 ...
- C#程序员知识体系
[https://blog.csdn.net/zj735539703/article/details/50409476] 基础部分 C# 基础语法 OOP的概念,面向对象的理解 继承 封装 多态 AS ...
- C# 处理PPT水印(二)——去除水印效果(文本水印、图片水印)
本文将对C#处理PPT幻灯片中的水印进一步说明和介绍.在C# 处理PPT水印(一)一文中,分享了如何插入水印效果的方法,包括插入文字水印效果.插入图片作为水印效果两种情况,那对于不需要水印效果的情况, ...
- Spring Boot入门-快速搭建web项目
Spring Boot 概述: Spring Boot makes it easy to create stand-alone, production-grade Spring based Appli ...
- 【转】Android播放音频MediaPlayer的几种方式介绍
接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...
- 用python爬取杭电oj的数据
暑假集训主要是在杭电oj上面刷题,白天与算法作斗争,晚上望干点自己喜欢的事情! 首先,确定要爬取哪些数据: 如上图所示,题目ID,名称,accepted,submissions,都很有用. 查看源代码 ...