面试题目

根据下面的配置文件
module=[
{'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},
{'name':'swfobject','src':'/js/utils/swfobject.js'},
{'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},
{'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},
{'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},
{'name':'register','src':'/js/page/reg.js','require':['jqform']},
{'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},
{'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','uploadify']}
]

写一个函数

def getfiles(name)

返回 加载某个name指定的页面,要加载的js文件列表,有依赖的要先加载

小菜解法

此题粗看起来很简单,实则不然。

难点在于依赖模块的加载时机。假如有这样的依赖关系:A-B&C、B-C,A模块依赖B模块和C模块,同时B模块又依赖了C模块,总不能让C加载两次吧!

小菜给出的这个解法,只是一个思路,肯定有比这更好的算法,小菜觉得可以用二叉树之类的算法解决,但小菜不会呀~~~

此算法没有考虑循环依赖的情景。

代码如下:

 /**
* 不考虑循环依赖
* @type {Function}
*/
var loadModule = (function(){
/**
* 业务逻辑封装
* @type {{chainHead: {}, chainCurrent: {}, srcCache: {}, main: main, load: load, findModule: findModule}}
*/
var logics = {
chainHead: {}, //链表头
chainCurrent: {}, //链表当前节点
srcCache: {}, //module src 缓存
/**
* 对外接口
* @param modules 配置对象
* @param name 模块名称
* @returns {Array} 依赖模块列表,按照加载先后顺序排列
*/
main: function(modules, name){
var nameArray = [], //模块名称列表
srcArray = [], //依赖模块列表
nameStr = "", //模块名称字符串集
repeatRegex = /(^| )([\w]+ ).*\2/, //模块名称去重正则
i = 0; //粗略加载所有依赖模块
this.load(modules, name) //构造模块名称字符串集
this.chainCurrent = this.chainHead;
while(this.chainCurrent.next){
nameArray.push(this.chainCurrent.name);
this.chainCurrent = this.chainCurrent.next;
}
nameStr = nameArray.join(" ") + " "; //统一标准,末尾补一个空格 //依赖模块去重
while(repeatRegex.exec(nameStr)){
nameStr = nameStr.replace(repeatRegex, function(g0, g1, g2){
return g0.substring(0, (g0.length - g2.length));
});
}
nameStr = nameStr.substring(0, (nameStr.length - 1)); //去掉补充的多余空格 //依赖模块名称转换为模块路径
nameArray = nameStr.split(" ");
for(i = 0; i < nameArray.length; i++){
srcArray.push(this.srcCache[nameArray[i]]);
} return srcArray;
},
/**
* 递归加载模块
* @param modules 配置对象
* @param name 模块名称
*/
load: function(modules, name){
var node = {},
module = this.findModule.call(modules, "name", name),
i = 0;
//判断模块是否存在
if(!module){
throw Error("依赖模块 " + name +" 未找到");
}
//构造模块依赖链表
node.name = name;
// node.src = module.src;
this.srcCache[name] = module.src;
node.next = this.chainHead;
this.chainHead = node;
//递归依赖
if(module.require && module.require.length){
for(i = 0;i < module.require.length; i++){
this.load(modules, module.require[i]);
}
}
},
/**
* 根据指定属性名称和属性值查找模块
* @param name 属性名称
* @param value 属性值
* @returns {*}
*/
findModule: function(name, value){
var array = this,
item = {},
i = 0;
//遍历模块
for(i = 0; i < array.length; i++){
item = array[i];
//获取指定模块
if(item && item[name] === value){
return item;
}
} //找不到返回null
return null;
}
}; //暴露对外接口
return function(){
return logics.main.apply(logics, arguments);
};
}()); /**
* Test Usecase
* @type {*[]}
*/ var modules=[
{'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},
{'name':'swfobject','src':'/js/utils/swfobject.js'},
{'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},
{'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},
{'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},
{'name':'register','src':'/js/page/reg.js','require':['jqform']},
{'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},
{'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','login','uploadify']}
]; console.log(loadModule(modules, "upload"));

根据配置文件加载js依赖模块(JavaScript面试题)的更多相关文章

  1. js怎么动态加载js文件(JavaScript性能优化篇)

    下面介绍一种JS代码优化的一个小技巧,通过动态加载引入js外部文件来提高网页加载速度 [基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完 ...

  2. Extjs4.1.x使用Application动态按需加载MVC各模块

    我们知道Extjs4之后提出了MVC模块开发,将以前肥厚的js文件拆分成小的js模块[model\view\controller\store\form\data等],通过controller拼接黏合, ...

  3. (转)高性能JavaScript:加载和运行(动态加载JS代码)

    浏览器是如何加载JS的 当浏览器遇到一个<script>标签时,浏览器首先根据标签src属性下载JavaScript代码,然后运行JavaScript代码,继而继续解析和翻译页面.如果需要 ...

  4. 页面加载异常 清除浏览器静态文件 js css 缓存 js动态加载js css文件,可以配置文件后辍,防止浏览器缓存

    js清除浏览器缓存的几种方法 - 兔老霸夏 - 博客园 https://www.cnblogs.com/Mr-Rocker/p/6031096.html js清除浏览器缓存的几种方法   一.CSS和 ...

  5. js动态加载js css文件,可以配置文件后辍,防止浏览器缓存

    js的引用,在浏览器,或微信上访问经常会遇到文件改了,但就是没有更新的问题,使用此函数可以轻松解决缓存问题只需要把js的引用方式改为使用此函数加载即可 源码如下: /** * js动态加载js css ...

  6. javascript动态加载js文件主流浏览器兼容版

    一.代码示例: <html> <head> <meta http-equiv="Content-Type" content="text/ht ...

  7. JavaScript 之 动态加载JS代码或JS文件

    2.动态加载JS文件 <script type="text/javascript"> function loadScript(url, callback) { var ...

  8. js文件加载太慢,JavaScript文件加载加速

    原文出自:https://blog.csdn.net/seesun2012 js脚本加载太慢,JavaScript脚本加载加速(亲测有效) 测试背景: JS文件大小:6.1kB 传统形式加载js文件: ...

  9. Confman - 针对「Node 应用」的配置文件加载模块

    一句话介绍 confman 是一个强大的配置文件加载器,无论你喜欢 yaml .cson.json.properties.plist.ini.toml.xml 还是 js,都能满足你的愿望,并且更加简 ...

随机推荐

  1. 从Unity引擎过度到Unreal4引擎(最终版)

    原文地址:http://demo.netfoucs.com/u011707076/article/details/44036839 前言 寒假回家到现在已经有十多天了,这些天回家不是睡就是吃....哎 ...

  2. VC++ list函数详解

    在使用之前,需要完成两件事: (1)  #include <list> (2)  using namespace std; 声名变量:   list<int>  intlist ...

  3. swift 代码添加lable

    let lable1 = UILabel(frame: CGRect(x: CGFloat(self.view.bounds.width/2-20), y: CGFloat(history.frame ...

  4. OA 办公自动化系统:权限管理模块的实现原理思路

    OA系统分有许多的模块,如系统管理模块.等一些比较高级的业务操作.此类业务是不允许让普通员工来操作的,思路如下: 给系统添加角色表,每个用户对应一个角色,每个角色可以拥有多个权限, 如下:创建权限表( ...

  5. Eclipse PHP Studio(EPP)

    Eclipse PHP Studio (EPP) 中文版官方网站 :http://epp.php100.com/ EclipsePHP Studio 简体中文版介绍 - EPP EclipsePHP ...

  6. flex 正则 验证

    验证数字:^[-]*$ 验证n位的数字:^\d{n}$ 验证至少n位数字:^\d{n,}$ 验证m-n位的数字:^\d{m,n}$ 验证零和非零开头的数字:^(|[-][-]*)$ 验证有两位小数的正 ...

  7. Servlet实现定时刷新到另外一个页面response.setHeader("refresh", "3;url=/...")

    想要实现,访问Responsedemo11的时候,3秒钟后,跳转到ResponseDemo10 用   response.setHeader("refresh", "3; ...

  8. php基础-转义字符

    1.php是弱类型语言,定义变量时无需要定义 2.标量类型:整形.浮点型.字符串类型.布尔型 复合类型:数组.对象 其它类型:资源类型(resource如数据库连接,打开文件句柄,资源在不需要时都要释 ...

  9. 梳理一下JS的基本语法

    web三层结构来说 结构层:HTML         从语义角度,描述页面结构 样式层:CSS         从审美的角度,美化页面 行为层:JavaScript   从交互的角度,提升用户体验   ...

  10. NX图标

    可以从%UGII_BASE_DIR%\ugii\menus目录下men文件或TBR文件中查找 关键字BITMAP 对应的名称