一、Javascript 模块化编程:
1、记的刚开始用JS写代码的时候,都是一个方法一个方法的处理某个事情,比如
function check(){
dosomething.....
}
这样写的好处就是方便,什么时候用,什么时候写,但是坏处就是污染了全局空间,很容易出现重复的名字,而且不容易维护。
2、后来想到了用命名空间来解决全局空间的问题,比如
var com={};
var com.do={};
com.do.get=function(){};
这样,方法名字就不会污染全局空间了,而且不同的人写的方法命名空间也会不一样,但是也有一个坏处那就是,每次调用一个方法的时候,都得写老长的名字,比如com.do.get(),这样很不人性化。
注:采用这种命名空间的写法,一个js文件就是一个模块,该模块中可以有私有方法和公有方法,公有方法可以供其他模块调用,比如
com.nuc.edu.cn.util = function () {
vartmp = null;
…
functionfun1() {} //私有方法1….
Return{
funA:function() {} //公有方法…
}
}
3、所以模块化的概念就出来了,把每一个功能集合放在一个模块里,每个想引用别的模块的功能是,调用require即可,目前模块化编程规范有CMD和AMD,下面我就拿玉seaJS模块类库来举例,怎么在程序里进行模块化编程。
使用seajs开发模块的时候,要遵守CMD规范,一个文件就是一个模块,比如项目中通常会定义一个通用的JS文件,放一些常有的功能,可以如下定义
//文件名为util.js
define(function(require,exports){
exports.showMsg(msg){
console.log(msg);
};
});
//页面中调用可以这样写
<script src="seajs.js"></script>
<script>
seajs.use("util",function(util){
util.showMsg("hello world!");
});
</script>
二、常见的模块化框架 require.js:
AMD提出了一种基于模块的异步加载JavaScript代码的机制,它推荐开发人员将JavaScript代码封装进一个个模块,对全局对象的依赖变成了对其他模块的依赖,无须再声明一大堆的全局变量。AMD典型的实现就是require.js
注:另外一个AMD的实现esl:https://github.com/ecomfe/esl
1、 引入require.js:
<script data-main="js/main"src="js/require-jquery.js"></script>
require.js 会检查 data-main 属性值,并加载指定的main.js
2、 define定义模块(命名空间):
1) 根据AMD规范,define是用来定义一个模块的(一个模块一个文件),有两个参数:第一个是数组,用来指定该模块依赖哪些其他模块,依赖关系需要顺序写到数组中(如果模块不依赖其他任何模块,改参数可以省略);第二个是回调函数,当加载完依赖后把要实现模块功能的代码写在该函数中;
注:引入依赖时不需要后缀名;
2) Define中的回调函数参数:加载了依赖关系后,依赖是通过参数传递的形式导入的。即:在回调函数中要使用某个依赖中的方法,直接通过参数调用即可。
3) 按照 RequireJS 的规范,所有的模块定义,都必须放在 return {} 对象中。也就是说,你的代码都要写在 return返回的 {} 对象里面。
define([‘jquery’,’jqgrid’],function ($,jqgrid){
function t1() {}//私有函数
function t2() {}
return {
fun1:function() {//公共函数
vartab = $(“#tab1”);
jqgrid.initGrid(…);
},
fun2:t2
}
})
例如:上面定义了一个fun.js文件,即:fun模块。该模块依赖jquery和jqgrid两个模块;该模块暴露了两个方法fun1和fun2;在模块中可以通过$和jqgrid这两个参数(别名)来使用jquery和jqgrid这两个模块中的方法。
注: jQuery 是从1.7版本开始才注册为 AMD 模块的。
3、 require加载js:
1) require 是用来加载其他模块的,他也有两个参数,第一个是数组,用来指定加载的模块;第二个是回调函数,当加载完后执行其中的代码(可选);
2) define 是你定义自己的模块的时候使用,可以顺便加载其他js;require 直截了当,供你加载用的,它就是一个加载方法,加载的时候,可以定义别名。
<script>
require( ["some" ] );
</script>
<script>
require(["aModule","bModule"], function() {
myFunctionA(); // 使用 aModule.js 中的函数 myFunctionA
myFunctionB(); // 使用 bModule.js 中的函数 myFunctionB
});
</script>
4、 其他:
1) 使用require.config()可以指定一些常用配置;
2) 当加载非AMD规范的define模块时,可以使用require.js中shim属性,直接使用其全局变量或函数就可以了,没有影响,这个时候只是控制了js 文件的加载顺序。
require.config({
paths: {
'jquery': 'jquery-1.4.1', // <= 模块 jquery 指向js/jquery-1.4.1.js 文件
'debounce':'libs/jquery-throttle-debounce.min'
},
shim: {
'jquery': {
exports: '$'
},
'debounce': {
deps: ['jquery']
}
}
});
require(['jquery','debounce'], function($){
console.log($.debounce);
});
注:exports 项,它的概念更接近imports,即把全局变量导入。
三、require.js 实例:
-目录结构:
|-index.html
|-js
|-require.js
|-jquery.js
|-main.js
-index.html
<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>require ceshi</title>
</head>
<script src="js/require.js"data-main="js/main"></script>
<body>
<table id="tab" boder=1>
<trid="abc"><td>1111111</td></tr>
</table>
</body>
</html>
-main.js
require(['jquery'], function($) {
var w = $(window).width();
alert(w);
});