<强>一、热身,先看实战代码强>
//定义及墙内部方法 ;(函数(窗口、函数未定义){ var的名字=扒健? 墙。说=function(名字){ 控制台。日志(“I \ ' m +名称+的!”); }; 墙。消息={ getName:函数(){ 返回名称; }, setName:函数(firstName, secondName) { name=firstName +“-”+ secondName; } }; })(窗口,窗口。墙| |(窗口。墙={})); >之前
& lt; script type=' text/javascript '比; & lt; %//Java代码直出js 都会(“Sniffer.run({“基地”:窗口,“名字”:“Wall.say”,“订阅”:真正的},“墙”);\ n”); %比;//Lab.js是一个文件加载工具//依赖的a.js加载完毕后,则可执行缓存的js方法 LAB.script美元(“a.js”) .wait(函数(){//触发已订阅的方法 Sniffer.trigger ({ “基地”:窗口中, “名称”:“Wall.say” }); }); & lt;/script> >之前这样,不管a.js文件多大,Wall.say(“墙”)都可以等到文件真正加载完后,再执行。
<强>二、工具简介强>
//执行Wall.message。setName(“王”,“墙”); Sniffer.run ({ “基地”:墙, “名称”:“message.setName”, “订阅”:真的 },“王”,“墙”);看这个执行代码,你也许会感觉困惑——什么鬼! & # 128518;
sniffer.js作用就是可以试探执行方法,如果不可执行,也不会抛错。
比如例子Wall.message。setName(“王”,“墙”);
如果该方法所在文件还没有加载,也不会报错。
处理的逻辑就是先缓存起来,等方法加载好后,再进行调用。
再次调用的方法如下:
//触发已订阅的方法 Sniffer.trigger ({ “基地”:墙, “名称”:“message.setName” });在线演示:https://wall-wxk.github.io/blogDemo/2017/02/13/sniffer。html(需要在控制台看,建议用pc)
说起这个工具的诞生,是因为公司业务的需要,自己写的一个工具。
因为公司的后台语言是java,喜欢用jsp的都会将()方法,直接输出一些js方法给客户端执行。
这就存在一个矛盾点,有时候js文件还没下载好,后台输出的语句已经开始调用方法,这就很尴尬。
所以,
<强> 强>
<强> 强>
<强>三,嗅探核心基础——运算符在强>
方法是通过使用运算符在去遍历命名空间中的方法,如果取得到值,则代表可执行。反之,则代表不可执行。
通过这个例子,就可以知道这个sniffer.js的嗅探原理了。
<强>四,抽象出嗅探方法强>
/* * * @function{私人}检测方法是否可用 * @param{字符串}funcName——方法名* * * * * * * * * * @param{对象}基地——方法所依附的对象 * */函数checkMethod (funcName基地){ var methodList=funcName.split(' . ')//方法名名单 readyFunc=基地,//检测合格的函数部分 结果={ “成功”:没错, 函数:函数(){} },//返回的检测结果 methodName,//单个方法名 我; (我=0;我& lt;methodList.length;我+ +){ methodName=methodList[我]; 如果(readyFunc methodName) { readyFunc=readyFunc [methodName]; 其他}{ 结果。成功=false; 返回结果; } } 结果。func=readyFunc; 返回结果; }<强> 强>
<强>五,实现缓存强>
缓存使用闭包实现的。以队列的性质,存储在列表中
;(函数(有趣,未定义){ 使用严格的 var列表=[];//存储订阅的需要调用的方法//执行方法 FUN.run=function () {//很多代码……//将订阅的函数缓存起来 list.push (…); }; })(窗口。嗅探器| |(窗口。嗅探器={})); >之前<强>六,确定队列中单个项的内容强>
由于运算符在工作时,需要几个基点给它检测,所以第一个要有的项就是基地
javaScript嗅探执行神器-sniffer.js