了解Javascript的模块化开发


Posted in Javascript onMarch 02, 2015

小A是某个创业团队的前端工程师,负责编写项目的Javascript程序。

全局变量冲突

根据自己的经验,小A先把一些常用的功能抽出来,写成函数放到一个公用文件base.js中:

var _ = {

    $: function(id) { return document.getElementById(id); },

    getCookie: function(key) { ... },

    setCookie: function(key, value) { ... }

};

小A把这些函数都放在_对象内,以防过多的全局变量造成冲突。他告诉团队的其他成员,如果谁想使用这些函数,只要引入base.js就可以了。

小C是小A的同事,他向小A反映:自己的页面引入了一个叫做underscore.js的类库,而且,这个类库也会占用_这个全局变量,这样一来就会跟base.js中的_冲突了。小A心想,underscore.js是第三方类库,估计不好改,但是base.js已经在很多页面铺开,不可能改。最后小A只好无奈地把underscore.js占用的全局变量改了。

此时,小A发现,把函数都放在一个名字空间内,可以减少全局变量冲突的概率,却没有解决全局变量冲突这个问题。

依赖

随着业务的发展,小A又编写了一系列的函数库和UI组件,比方说标签切换组件tabs.js,此组件需调用base.js以及util.js中的函数。

有一天,新同事小D跟小A反映,自己已经在页面中引用了tabs.js,功能却不正常。小A一看就发现问题了,原来小D不知道tabs.js依赖于base.js以及util.js,他并没有添加这两个文件的引用。于是,他马上进行修改:

<script src="tabs.js"></script>

<script src="base.js"></script>

<script src="util.js"></script>

然而,功能还是不正常,此时小A教训小D说:“都说是依赖,那被依赖方肯定要放在依赖方之前啊”。原来小D把base.js和util.js放到tabs.js之后了。

小A心想,他是作者,自然知道组件的依赖情况,但是别人就难说了,特别是新人。

过了一段时间,小A给标签切换组件增加了功能,为了实现这个功能,tabs.js还需要调用ui.js中的函数。这时,小A发现了一个严重的问题,他需要在所有调用了tabs.js的页面上增加ui.js的引用!!!

又过了一段时间,小A优化了tabs.js,这个组件已经不再依赖于util.js,所以他在所有用到tabs.js的页面中移除了util.js的引用,以提高性能。他这一修改,出大事了,测试组MM告诉他,有些页面不正常了。小A一看,恍然大悟,原来某些页面的其他功能用到了util.js中的函数,他把这个文件的引用去掉导致出错了。为了保证功能正常,他又把代码恢复了。

小A又想,有没有办法在修改依赖的同时不用逐一修改页面,也不影响其他功能呢?

模块化

小A逛互联网的时候,无意中发现了一种新奇的模块化编码方式,可以把它之前遇到的问题全部解决。

在模块化编程方式下,每个文件都是一个模块。每个模块都由一个名为define的函数创建。例如,把base.js改造成一个模块后,代码会变成这样:

define(function(require, exports, module) {

    exports.$ = function(id) { return document.getElementById(id); };

    exports.getCookie = function(key) { ... };

    exports.setCookie = function(key, value) { ... };

});

base.js向外提供的接口都被添加到exports这个对象。而exports是一个局部变量,整个模块的代码都没有占用半个全局变量。

那如何调用某个模块提供的接口呢?以tabs.js为例,它要依赖于base.js和util.js:

define(function(require, exports, module) {

    var _ = require('base.js'), util = require('util.js');

    var div_tabs = _.$('tabs');

    // .... 其他代码

});

一个模块可以通过局部函数require获取其他模块的接口。此时,变量_和util都是局部变量,并且,变量名完全是受开发者控制的,如果你不喜欢_,那也可以用base:
define(function(require, exports, module) {

    var base = require('base.js'), util = require('util.js');

    var div_tabs = base.$('tabs');

    // .... 其他代码

});

一旦要移除util.js、添加ui.js,那只要修改tabs.js就可以了:
define(function(require, exports, module) {

    var base = require('base.js'), ui = require('ui.js');

    var div_tabs = base.$('tabs');

    // .... 其他代码

});

加载器

由于缺乏浏览器的原生支持,如果我们要用模块化的方式编码,就必须借助于一个叫做加载器(loader)的东西。

目前加载器的实现有很多,比如require.js、seajs。而JRaiser类库也有自己的加载器。

Javascript 相关文章推荐
js压缩工具 yuicompressor 使用教程
Mar 31 Javascript
基于jquery的仿百度搜索框效果代码
Apr 11 Javascript
jQuery中removeProp()方法用法实例
Jan 05 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
Apr 27 Javascript
多种JQuery循环滚动文字图片效果代码
Jun 23 Javascript
JavaScript闭包和范围实例详解
Dec 19 Javascript
Vue2.0利用vue-resource上传文件到七牛的实例代码
Jul 28 Javascript
在ABP框架中使用BootstrapTable组件的方法
Jul 31 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
May 10 Javascript
原生js实现的观察者和订阅者模式简单示例
Apr 18 Javascript
VUE+Element实现增删改查的示例源码
Nov 23 Vue.js
Ajax实现页面无刷新留言效果
Mar 24 Javascript
JS实现的4种数字千位符格式化方法分享
Mar 02 #Javascript
js实现图片漂浮效果的方法
Mar 02 #Javascript
ECMAScript 5中的属性描述符详解
Mar 02 #Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
Mar 02 #Javascript
JavaScript数组常用方法
Mar 02 #Javascript
使用npm发布Node.JS程序包教程
Mar 02 #Javascript
js实现点击链接后窗口缩小并居中的方法
Mar 02 #Javascript
You might like
星际争霸 Starcraft 编年史
2020/03/14 星际争霸
php实现递归与无限分类的方法
2015/02/16 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
PHP接口并发测试的方法(推荐)
2016/12/15 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
2019/12/02 PHP
js技巧--转义符&quot;\&quot;的妙用
2007/01/09 Javascript
图片自动缩小的js代码,用以防止图片撑破页面
2007/03/12 Javascript
Javascript 原型和继承(Prototypes and Inheritance)
2009/04/01 Javascript
js 验证身份证信息有效性
2014/03/28 Javascript
jQuery DOM插入节点操作指南
2015/03/03 Javascript
详解Angular.js的$q.defer()服务异步处理
2016/11/06 Javascript
JavaScript中的编码和解码函数
2017/02/15 Javascript
JS实现异步上传压缩图片
2017/04/22 Javascript
vue的Virtual Dom实现snabbdom解密
2017/05/03 Javascript
Gulp实现静态网页模块化的方法详解
2018/01/09 Javascript
微信小程序自定义音乐进度条的实例代码
2018/08/28 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
微信小程序地图导航功能实现完整源代码附效果图(推荐)
2019/04/28 Javascript
详解使用mocha对webpack打包的项目进行&quot;冒烟测试&quot;的大致流程
2020/04/27 Javascript
用map函数来完成Python并行任务的简单示例
2015/04/02 Python
django-rest-framework 自定义swagger过程详解
2019/07/18 Python
通过python实现windows桌面截图代码实例
2020/01/17 Python
韩国家庭购物网上商店:Nsmall
2017/05/07 全球购物
花园仓库建筑:Garden Buildings Direct
2018/02/16 全球购物
世界上第一个创建了罩杯系统的美国内衣品牌:Maidenform
2019/03/23 全球购物
设计师大码女装:11 Honoré
2020/05/03 全球购物
与UNIX有关的几个名词
2015/09/17 面试题
教师个人自我评价范文
2014/04/13 职场文书
爱护公物演讲稿
2014/09/09 职场文书
殡葬服务心得体会
2014/09/11 职场文书
2014年信息宣传工作总结
2014/12/18 职场文书
毕业证明模板
2015/06/19 职场文书
担保书怎么写 ?
2019/04/22 职场文书
python基础学习之递归函数知识总结
2021/05/26 Python
Python中glob库实现文件名的匹配
2021/06/18 Python
Go语言基础知识点介绍
2021/07/04 Golang