手机版

javaScript嗅探器执行工件

时间:2021-09-06 来源:互联网 编辑:宝哥软件园 浏览:

一、热身——先看实战代码

A.js文件

//定义Wall和内部方法;(函数(窗口,FUNC,未定义){ var name=' wallwall . say=function(name){ console . log('我是' name '!');};wall . message={ getName : function(){ return name;},setName :函数(firstName,second name){ name=first name '-' second name;} };})(窗口,窗口。墙||(窗户。wall={ }));Index.jsp文件

脚本类型=' text/JavaScript'%//Java代码直截了当jsout . print(' sniffer . run({ ' base ' : window,' name' :' wall.say ',' subscribe' : true},' wall ');\ n ');% //Lab.js是一个文件加载工具。//加载依赖的a.js后,缓存的js方法$ lab.script ('a.js ')。wait(function(){//触发订阅的方法sniffer . trigger({ ' base ' : window,' name ' 33330)});/script这样,无论a.js文件有多大,Wall.say('wall ')都可以等到文件真正加载后再执行。

二、工具介绍

//执行wall.message.setname ('Wang ',' wall ');Sniffer.run({ 'base':Wall,' name':'message.setName ',' subscribe':true ',' wang ',' wall ');看看这段执行代码,你可能会感到困惑——搞什么鬼!

sniffer.js的功能是探查执行方法,如果不能执行就不会抛出错误。

示例wall.message.setname ('Wang ',' wall ');

如果方法所在的文件尚未加载,则不会报告错误。

处理的逻辑是先缓存它,然后在加载方法后调用它。

再次调用的方法如下:

//触发订阅的方法sniffer . trigger({ ' base ' : wall,' name ' : ' message . set name ' });在线演示:https://wall-wxk . github . io/blog demo/2017/02/13/sniffer . html(需要在控制台观看,建议使用pc)

说起这个工具的诞生,正是因为公司业务的需要,我自己写了一个工具。

因为公司的后台语言是java,所以我喜欢用jsp的out.print()方法直接输出一些js方法给客户端执行。

有一个矛盾。有时候js文件还没有下载好,后台输出的语句已经开始调用方法了,很尴尬。

因此,这个工具有两个功能:

1.检测执行的js方法是否存在,如果存在,立即执行。

2.缓存暂时不存在的js方法,然后将它们从缓存队列中取出,以便在真正可执行时触发执行。

第三,嗅探核心基础——运算符

方法是使用中的运算符遍历命名空间中的方法,如果获得了值,则表示可执行。否则,意味着不可执行。

操作员输入

通过这个例子,我们可以知道sniffer.js的嗅探原理

第四,抽象嗅探方法

/*** @function {private}检测方法是否可用* @param {string} funcName -方法名***。* * *.* * * * @ param { object } Base-方法附加到的对象* */functioncheckmethod(funcname,Base) {var method list=funcname。拆分('.'),//方法名列表readyFunc=base,//测试限定函数部分结果={'success' : true,' func' : function () {},//返回测试结果method name,//single for(I=0;i methodList.lengthI){ method name=method list[I];if(ReadyFuc中的method name){ ReadyFuc=ReadyFuc[method name];} else { result.success=false返回结果;} } result.func=readyFunc返回结果;}喜欢wall.message.setname ('Wang ',' wall ');要判断这样的方法是否可以执行,需要执行以下步骤:

1.判断窗口中是否存在Wall。

2.如果wall存在,继续判断消息是否在Wall中。

3.如果消息存在,继续判断消息中是否有setName

4.最后,如果判断存在,则表示可以执行。如果任何中间测试失败,该方法将无法执行。

第五,实现缓存

缓存是使用闭包实现的。就队列的性质而言,它存储在列表中

;(函数(FUN,undefined){ ' use strict ' var list=[];//存储要调用的订阅方法//执行方法FUN.run=function(){ //大量代码.//缓存订阅的函数列表.);};})(窗口。嗅探器||(窗口。sniffer={ }));第六,确定队列中单个项目的内容

1.指定检测基准的基点

因为操作员在工作,所以需要几个基点来检测它。所以首先要有基础

2.检测到的字符类型的方法名称

像wall.message.setname ('wang ',' wall ');如果已指定基点{'base':Wall},还需要message.setName。因此,存储message.setName,即{'base' : wall,' name' :' message.setname'}

3.缓存方法的参数参数

像wall.message.setname ('wang ',' wall ');有两个参数(' wang ',' wall '),所以需要存储。也就是{ '基地' :墙,'名字' : '消息。集名',' args' : ['Wang ',' wall']}。

之所以用数组缓存参数,是因为方法的参数发生了变化,所以后续的代码需要应用于触发器。同样,这里的参数需要缓存在数组中

因此,缓存队列中单个条目的内容如下:

{'base' : wall,' name' : '消息。集名',' args' : ['王','墙']} VII。实现运行方法

;(函数(FUN,undefined){ ' use strict ' var list=[];//存储要调用的订阅方法/* * * @函数转换接口,用于判断函数在命名空间中是否存在。如果是,就调用,如果不是,就不调用* @ version {create} 2015-11-30 * @说明*用法:只为延迟加载设计*示例:Wall.mytext.init(45,false);* call:sniffer . run({ ' base ' : window,' name' :' wall.mytext.init'},45,false);或者sniffer.run ({'base' : wall,' name' :' mytext.init'},45,false);*如果不知道参数个数,不能直接写,可以通过apply调用当前方法*示例: sniffer.run.apply (window,[{ ' name ' : ' wall . mytext . init ' },45,false];* */FUN . run=function(){ if(arguments . length 1 | | type of arguments[0]!=' object '){抛出新错误(' sniffer。运行参数错误’);返回;} var name=参数[0]。name,//函数名的0位为Object类型,便于扩展。subscribe=参数[0]。订阅| | false,//订阅。函数可执行时,调用函数,true:订阅;True :不订阅prompt=参数[0]。提示| |假。//是否显示提示(函数执行失败时)?Promptmsg=参数[0]。“函数仍在加载,请稍候”。//函数未能执行提示基=参数[0]。base | | window,//benchmark对象,函数搜索的起点args=array。prototype.slice.call(参数),//参数列表funcArgs=args.slice(1),//参数列表回调func={//test result=check method(name,base);if(result . success){ subscribe=false;尝试{ return result . func . apply(result . func,Funcargs);//将调整函数的指针指向}catch(e){(控制台类型!=' undefined ')console . log console . log('错误:name=' e.namemessage=' e . message);} }else{ if(prompt){ //输出提示到页面,代码略} }//缓存订阅的函数if(subscribe){ callbackfunc . name=name;callbackFunc.base=basecallbackFunc.args=funcArgslist . push(callbackFunc);} };//嗅探方法函数检查方法(funcname,base){//代码.} })(window . sniffer | |(window . sniffer={ });run方法的功能是检查该方法是否可以执行,如果可以,则执行它。如果不可执行,根据传入的参数决定是否缓存。

这个run方法的重点是巧妙地利用参数实现0-n个参数的自由引入。

第一个参数,参数[0],对于传入配置项是固定的。存储要检测的基点,方法字符串参数[0]。名称和缓存标志参数[0]。

当第二个参数转到第n个参数时,方法调用方传入要使用的参数。

使用泛型方法,参数被转换成实数组。(args=array . prototype . slice . call(参数))

然后,删除方法调用所需的参数。(funcArgs=args.slice(1))

在运行方法的参数被处理之后,您可以调用checkMethod方法进行嗅探。

根据嗅探的结果,有两种情况:

如果嗅探结果是可执行的,调用apply for execution

返回result.func.apply(result.func,Funcargs);

这里强调的是作用域必须设置为result.func,也就是这个例子的Wall.message.setName。

这样,如果在方法中使用这种方法,指向就不会改变。

使用Return是因为有些方法在执行后有返回值,所以需要在这里加上return,将返回值传递出去。

如果嗅探结果不可执行,则根据传入的配置值subscribe决定是否将其缓存在队列列表中。

如果需要缓存,请拼接队列中的单个项目,并将它们推入列表。

八、实施触发方法

;(函数(FUN,undefined){ ' use strict ' var list=[];//存储要调用的订阅方法//执行方法FUN.run=function(){ //代码.};/* * * @函数触发函数接口,调用已经提前订阅的函数* @ param {object}选项需要调用的相关参数* @说明*用途:仅设计用于延迟加载*另外,调用触发方法的前提条件是,订阅方法所在的js已经加载解析。*无论触发是否成功,列表中相应的项目将被清除。* */fun.trigger=函数(选项){if(选项的类型!==' object '){抛出新错误(' sniffer。触发器参数错误’);返回;} var funcname=option。name | | ' ',//函数名base=option.base || window,//benchmark对象,函数搜索的起点newList=[],//用于更新列表结果,//测试结果func,//执行方法的存储指针I,//遍历列表参数;//临时存储列表[I] console.log (funcname在base中);if(FuncName . length 1){ return;}//遍历列表,执行相应的函数,将其从缓存池列表中删除为(I=0;一、清单.长度;I){ param=list[I];if(param . name==FuncTion name){ result=CheckMethod(FuncTion name,base);if(result . success){ try { result . func . apply(result . func,param . args);}catch(e){(控制台类型!=' undefined ')console . log console . log('错误:name=' e.namemessage=' e . message);} } } else { NewList . push(param);} } list=newList};//嗅探方法函数检查方法(funcname,base){//代码.} })(window . sniffer | |(window . sniffer={ });如果理解了前面的run方法,那么trigger方法就不难理解了。

1.首先,告诉触发器方法需要从队列列表中取出哪个方法来执行。

2.在执行该方法之前,您需要再次嗅探该方法是否已经存在。只有当它存在时,它才能被执行。否则,可以认为该方法不再存在,可以从缓存中删除。

九.实用性和可靠性

实用性毋庸置疑,不管什么代码栈,Sniffer.js都值得拥有!

在可靠性方面,Sniffer.js已经在高流量公司产品中使用,到目前为止没有出现反馈兼容性或性能问题。这方面也可以保证!

最后,附上源代码地址:https://github.com/wall-wxk/sniffer/blob/master/sniffer.js.

以上就是本文的全部内容。希望本文的内容能给大家的学习或工作带来一些帮助,也希望多多支持我们!

版权声明:javaScript嗅探器执行工件是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。