1 / 18
文档名称:

JavaScript模块化开发.docx

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

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

分享

预览

JavaScript模块化开发.docx

上传人:yzhluyin1 2016/12/23 文件大小:45 KB

下载得到文件列表

JavaScript模块化开发.docx

相关文档

文档介绍

文档介绍:## 前言 The Module Pattern ,模块模式,也译为模组模式,是一种通用的对代码进行模块化组织与定义的方式。这里所说的模块( Modules ),是指实现某特定功能的一组方法和代码。许多现代语言都定义了代码的模块化组织方式,比如 Golang 和 Java ,它们都使用 package 与 import 来管理与使用模块,而目前版本的 JavaScript 并未提供一种原生的、语言级别的模块化组织模式,而是将模块化的方法交由开发者来实现。因此, 出现了很多种 JavaScript 模块化的实现方式, 比如, CommonJS Modules 、 AMD 等。以 AMD 为例,该规范使用 define 函数来定义模块。使用 AMD 规范进行模块化编程是很简单的,大致上的结构是这样的: 1define(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 对象就在模块内直接引用$ 这个对象,是有出错的可能的。正确的方式大致应该是这样的: 1;(function (q, w){2//qisjQuer