模块化的由来:
随着前端业务越来越庞大,javascript代码的体量和职责也越来越大。由于javascript语言本身的特性没有继承和封装的概念,因此需要一种规范来约束js代码块的功能职责,使之完成自己的职责,同时不会对其他的部分造成污染。前端模块化的想法应运而生。
模块化的定义:
模块就是实现特定功能的相互独立的一组方法。
模块化的意义:
开发者能够随心所欲的饮用不同的功能,组织自己的代码实现相应的业务逻辑,而不需要考虑全局污染的问题。之前对于不同代码块的引入方式是通过script标签。这种方式由于不同的空间写法不一样,使用方式没有统一的规范,同时有可能会污染到全局的作用域。因此这种手工的方式十分的不规范而繁琐。需要一种统一的规范。使开发者能够不用便捷的使用到其他模块的方法。
两种模块化的规范:AMD + CommonJS,该篇主要讨论AMD。
AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一个可用的模块化 JavaScript 的解决方案。它诞生于 Dojo 在使用 XHR+eval 时的实践经验,其支持者希望未来的解决方案都可以免受由于过去方案的缺陷所带来的麻烦。
作为一个模块,需要定义什么?定义define+依赖require
define(
module_id , // 模块的命名
[dependencies] , // 模块的依赖,需要指明该模块依赖于哪些其他的模块
definition function /*用来初始化模块或对象的函数*/
);
module_id: 模块的id,并非必须指定。如果没有指定,则是匿名模块
dependencies: 依赖项,指明该模块依赖于哪些其他模块的功能。
definition:function,模块的构造器。定义模块的方法,并提供暴露到外部的接口。
例子:
define('myModule', [req1', 'req2'], function(req1,req2){ // 传入依赖项1和依赖项2的引用
var myModule = {
doSth: function(){console.log("heihei");}
}
return myModule;
})
require(['req1,req2'], function(req1,req2){
req1.doSth();
req2.doSth();
})
动态依赖:
define('myModule',function(){
require(['req1','req2'],function(req1,req2){
req1.doSth();
req2.doSth();
})
var myModule = {
doSth: function(){console.log("heiheihei");}
}
return myModule;
})
require函数指定定义的模块需要哪些依赖项,同时在引入的时候,可以做一些初始化工作。
AMD与设计模式:
由于define是返回什么,用户在require的时候就能获得什么。所以define可以跟设计模式结合起来做一些事情。
单例模式:
define(function(){
var instance;
function Singlton(){
this.defaultData = "";
}
Singlton.prototype = {
doSth: function(){
alert("你打我啊");
},
setDefault: function(data){
this.defaultData = data;
}
}
return function getInstance(){
return instance = instance || new Singlton();
}
})
装饰器模式:接受一个基类,包装好了返回即可
define(function(observal){
return function updateObserval(store){
var observal = typeof store === 'function'? store: new observal(store);
observal.doSth = function(){
alert("decorator 你打我啊");
}
return observal;
}
})