1 / 17
文档名称:

JavaScript模块化开发.docx

格式:docx   大小:45KB   页数:17页
下载后只包含 1 个 DOCX 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

JavaScript模块化开发.docx

上传人:taotao0c 2017/9/8 文件大小:45 KB

下载得到文件列表

JavaScript模块化开发.docx

文档介绍

文档介绍:## 前言
The Module Pattern,模块模式,也译为模组模式,是一种通用的对代码进行模块化组织与定义的方式。这里所说的模块(Modules),是指实现某特定功能的一组方法和代码。许多现代语言都定义了代码的模块化组织方式,比如 Golang 和 Java,它们都使用 package 与 import 来管理与使用模块,而目前版本的 JavaScript 并未提供一种原生的、语言级别的模块化组织模式,而是将模块化的方法交由开发者来实现。因此,出现了很多种 JavaScript 模块化的实现方式,monJS Modules、AMD 等。
以 AMD 为例,该规范使用 define 函数来定义模块。使用 AMD 规范进行模块化编程是很简单的,大致上的结构是这样的:
1
define(factory(){
2
  // 模块代码
3
  // return something;
4
});
目前尚在制定中的 Harmony/ECMAScript 6(也称为 ),会对模块作出语言级别的定义,但距离实用尚遥不可及,这里暂时不讨论它。
作为一种模式,模块模式其实一直伴随着 JavaScript 存在,与 ES 6 无关。最近我需要重构自己的一些代码,因此我参考和总结了一些实用的模块化编程实践,以便更好的组织我的代码。需要注意的是,本文只是个人的一个总结,比较简单和片面,详尽的内容与剖析请参看文后的参考资料,它们写得很好。本文并不关心模块如何载入,只关心现今该如何组织模块化的代码。还有,不必过于纠结所谓的模式,真正重要的其实还是模块代码及思想。所谓模式,不过是我们书写代码的一些技巧和经验的总结,是一些惯用法,实践中应灵活运用。
## 模块模式
### 闭包与 IIFE (Immediately-Invoked Function Expression)
模块模式使用了 JavaScript 的一个特性,即闭包(Closures)。现今流行的一些 JS 库中经常见到以下形式的代码:
1
;(function (参数) {
2
  // 模块代码
3
  // return something;
4
})(参数);
上面的代码定义了一个匿名函数,并立即调用自己,这叫做自调用匿名函数(SIAF),更准确一点,称为立即调用的函数表达(Immediately-Invoked Function Expression, IIFE–读做“iffy”)。
在闭包中,可以定义私有变量和函数,外部无法访问它们,从而做到了私有成员的隐藏和隔离。而通过返回对象或函数,或是将某对象作为参数传入,在函数体内对该对象进行操作,就可以公开我们所希望对外暴露的公开的方法与数据。
这,其实就是模块模式的本质。
注1:上面的代码中,最后的一对括号是对匿名函数的调用,因此必不可少。而前面的一对围绕着函数表达式的一对括号并不是必需的,但它可以用来给开发人员一个指示-- 这是一个 IIFE。也有一些开发者在函数表达式前面加上一个惊叹号(!)或分号(;),而不是用括号包起来。比如 knockoutjs 的源码大致就是这样的:
1
!function (参数) {
2
  // 代码
3
  // return something
4
}(参数);
还有些人喜欢用括号将整个 IIFE 围起来,这样就变成了以下的形式:
1
(function (参数) {
2
  // 代码
3
  // return something
4
}(参数));
注2:在有些人的代码中,将 undefined 作为上面代码中的一个参数,他们那样做是因为 undefined 并不是 JavaScript 的保留字,用户也可以定义它,这样,当判断某个值是否是 undefined 的时候,判断可能会是错误的。将 undefined 作为一个参数传入,是希望代码能按预期那样运行。不过我认为,一般情况下那样做并没太大意义。
### 参数输入
JavaScript 有一个特性叫做隐式全局变量(implied globals),当使用一个变量名时,JavaScript 解释器将反向遍历作用域链来查找变量的声明,如果没有找到,就假定该变量是全局变量。这种特性使得我们可以在闭包里随处引用全局变量,比如 jQuery 或 window。然而,这是一种不好的方式。
考虑模块的独立性和封装,对其它对象的引用应该通过参数来引入。如果模块内需要使用其它全局对象,应该将这些对象作为参数来显式引用它们,而非在模块内直接引用这些对象的名字。以 jQuery 为例,若在参数中没有输入 jQuery 对象就在模块内直接引用$ 这个对