封装
1、函数 直接调用函数 会更改全局变量 模块之间关系不明显
function m1(){
//...
}
2、对象 用对象的属性来获取 能通过属性呗外部改写 会暴露模块成员
var module1 = new Object({
_count : 0,
m1 : function (){
//...
},
m2 : function (){
//...
}
});
3、立即执行函数 外部无法更改内部内容 也不会暴露私有成员
var module1 = (function(){
var _count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
4、放大模式 一个模块太大 需要分成几块 或者继承另一个模块
var module1 = (function (mod){
mod.m3 = function () {//module1添加了一个方法m3 返回新的module1
//...
};
return mod;
})(module1);
5、宽放大模式 与方法模式比 就是参数可以是个空的对象
var module1 = ( function (mod){
//...
return mod;
})(window.module1 || {});
6、输入全局变量 为了模块内调用全局变量
var module1 = (function ($, YAHOO) {
//...
})(jQuery, YAHOO);
模块的方法
1、comminJS 主要为js后端的表现制定的 不适合浏览器环境 同步加载 会导致浏览器假死 一直在加载模块
var math = require('math');
math.add(2, 3);
2、AMD 推崇依赖前置 AMD 是 RequireJS 在推广过程中对模块定义的规范化产出 AMD 是提前执行 适用于浏览器端
require([module], callback);//module里面是要加载的模块
require(['math'], function (math) {
//math.add()与math模块加载不是同步的,浏览器不会发生假死
math.add(2, 3);
});
3、CMD 推崇依赖就近 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出 CMD 是延迟执行 适用于浏览器端
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ... })
4、ES6自带的模块化
//导出常量
export const sqrt = Math.sqrt;
//导出函数
export function square(x) {
return x * x;
}
//导出函数
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
import { square, diag } from './lib';
实现AMD:require.js
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
下载require.js
加载该文件 制定网页程序主模块 放在网页底部
<script src="js/require.js" defer async="true" data-main="js/main"></script>
写main.js
// main.js
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"
}
});
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
});
下载优化工具
require.js要求 每个模块是一个单独的js文件 这样的话,如果加载多个模块,就会发出多次HTTP请求 会影响网页的加载速度 因此,require.js提供了一个优化工具 当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中 减少HTTP请求数
AMD模块的写法
// math.js
//如果该模块不引用其他模块
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});
//如果该模块还需要引用其他模块
define(['myLib'], function(myLib){
function foo(){
myLib.doSomething();
}
return {
foo : foo
};
});
// main.js
//此处引用模块math
require(['math'], function (math){
alert(math.add(1,1));
});
加载非规范模块
理论上 require.js加载的模块 必须是按照AMD规范 即用define()函数定义的模块
//举例:加载underscore和backbone这两个库
require.config({
shim: {
'underscore':{
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],//表明该模块的依赖性
exports: 'Backbone'//表明这个模块外部调用时的名称
}
}
});
require.js插件
原文:
Javascript模块化编程(一):模块的写法
Javascript模块化编程(二):AMD规范
Javascript模块化编程(三):require.js的用法