了解Javascript的模块化开发

小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类库也有自己的加载器。

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
1,onload事件 复制代码 代码如下: !DOCTYPE HTML HTML HEAD meta charset="utf-8" / titleLink Element onload/title link type="text/css" rel="stylesheet" href=#>/HEAD BODY /BODY /HTML IE6/7 : IE8/9 : Opera : 即IE6/7/8/9/Opera都支持onload事件, Firefox/Safari/Chrome不支持。 注:用JS创建li
在线演示 我们曾经介绍过俩款知名的响应式布局插: isotope 和 masonary ,今天我们这里再介绍一款相当不错的响应式布局插件
JavaScript的语法有多坑,算是众人皆知了。 先来上张图 代码如下: 复制代码 代码如下: {} + []; // 0 [] + {}; // "[object Object]" {} + [] == [] + {}; // false ({} + [] == [] + {}); // true 这么蛋疼的语法坑估计也只有 JavaScript 这样的奇葩才有。 相信对于绝大部分不研究 JavaScript 编译器的童鞋,根本无法理解。(至少我也是觉得不可思议) 后来专门去度娘了一下,才有点恍然大悟
版本一 css代码部分: 复制代码 代码如下: .focus { border: 1px solid #f00; background: #fcc; } 当焦点获得时,添加focus样式,添加边框,并改背景色为#fcc html代码部分: 复制代码 代码如下: body form action="" method="post" id="regForm" fieldset legend个人基本信息/legend div label for="username"名称:/label input id="user
CheckBox控件就是我们一般所说的复选框,通常用于某选项的打开或关闭。大多数应用程序的“设置”对话框内均有此控件。我们看到的可以打勾的就是CheckBox。 该控件表明一个特定的状态(即选项)是选定 (on,值为1) 还是清除 (off,值为0)。在应用程序中使用该控件为用户提供“True/False”或“yes/no”的选择。因为 CheckBox 彼此独立工作,所以用户可以同时选择任意多个 CheckBox,进行选项组合。 CheckBox复选框JS实现全选全不选功能,很简单,就只需插入一小段js
extjs提供了方便的表格组件grid供使用,但是默认情况下表格中的文本是不能被选中的,自然也是无法复制的。 而选择复制文本的需要也是很平常的,于是我们就需要自己动手来解决这个问题,实现extjs的grid文本选择复制功能。 说明一点,文中所列出的代码片断都是在当前ext 4.0.2a版本下的,其它版本未做测试,请自行斟酌。 首先自定义一下样式,来覆盖默认的css样式: 复制代码 代码如下: style type="text/css" .x-selectable, .x-selectable * { -mo
文件上传之前的检测,通常是通过文件名来判断文件类型是否合法,但是要想检测文件的大小很难办到,除非在本地或者使用控件。使用JS可以轻松解决词问题,js在上传图片前判断大小 这个可以用javascript实现,效果...//允许上传图片文件的大小 具体代码如下 复制代码 代码如下: script language=javascript var ImgObj=new Image(); //建立一个图像对象 var AllImgExt=".jpg|.jpeg|.gif|.bmp|.png|"//全部图片格式类型 v
复制代码 代码如下: Ext.onReady(function(){ //定义store var chartStore = new Ext.data.JsonStore({ root:'root', fields:[ {name:'ne',type:'string'},//网元 {name:'confine',type:'int'},//阀值 {name:'bill',type:'string'}//工单数 ], sortInfo:{field: 'bill', direction: 'ASC'} });
JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么? 原始发布:Dmitry A. Soshnikov 发布时间:2009-06-27 俄文地址:http://dmitrysoshnikov.com/ecmascript/ru-chapter-2-variable-object/ 英文翻译:Dmitry A. Soshnikov 发布时间:2010-03-15 英文地址:http://dmi
复制代码 代码如下: %@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"% !DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" html head meta http-equiv="Content-Type" content="text/htm