(function(){ //存储已经创建的模块 var moduleMap = {}; //判断是否已经加载过 var fileMap = {}; //空函数 var noop = function(){}; /*注册为全局变量*/ window.thin = { //在这里定义的模块,都被注册到了moduleMap里面 /*define :主要作用moduleMap中注册模块 *name 模块的名称 *dependencies 模块的依赖项 *factory 模块的函数体 */ define:function(name,dependencies,factory){ if(!moduleMap[name]){ //模块的结构 var module = { name:name, dependencies:dependencies, factory:factory }; moduleMap[name] = module; } return moduleMap[name] }, /*use: 主要作用得到模块的使用权 *name 模块的名称 * */ use:function(name){ //module 需要使用的模块的引用 var module = moduleMap[name]; if(!module.entity){ //用来存储依赖项引用,用于传入factory,方便函数调用 var args = []; //遍历module的依赖项数组 for(var i=0;i<module.dependencies.length;i++){ //检测依赖项数组的entity属性,如果已经使用,获取引用 if(moduleMap[module.dependencies[i].entity]){ args.push(moduleMap[module.dependencies[i]].entity) } //如果没有使用,则获取这个模块的使用权 else{ args.push(this.use(module.dependencies[i])) } } module.entity = module.factory.apply(noop,args) //noop 空函数 } return module.entity; }, /*实现按需加载模块,而不是一次性加载所有模块 *实现原理:动态创建script标签,设置src,添加到document.head,监听完成的事件 *fileMap 记录已经加载的文件的路径,防止重复加载,当所有加载完,执行回调 */ require:function(pathArr,callback){ for(var i = 0;i<pathArr.length;i++){ var path = pathArr[i]; //如果还没有加载 if(!fileMap[path]){ var head = document.getElementByTagName("head")[0]; var node = document.createElement("script"); node.type= "text/javascript"; node.async="true"; node.src = path+".js"; //当加载完成后, node.onload = function(){ fileMap[path] = true; head.removeChild(node); checkAllFiles(); }