在腾讯的AlloyTeam的Blog上发现了这样的一款工具:AlloyLever(原blog地址:http://www.alloyteam.com/2016...),以为很是有趣且实用。尤为是其实现的原理也并不复杂,却能够给日常的调试工做带来巨大的便利,不得不让人感叹凡事就怕认真啊。git
这个就是这款工具的样子,它整合了web调试中几个很是频繁的刚需:看log、看error、看AJAX发包与回包。同时还附有查看timeline、cookie和localStorage的这些功能。虽然这些信息在chrome的调试工具里面也是触手可及,但是因为涉及的缘由,他们被放在跟原web页面不相关的一个窗口里,还分了不少的标签页,在实际工做中,一个web页面+F12的调试窗口常常就占满了整个屏幕,着实是有些不太方便。这也是这个工具最初被制造出来,想要解决的问题吧。github
这个工具的实现原理,是很简单的函数劫持。有关于函数劫持的相关知识,可参见这篇文章(https://segmentfault.com/a/11...),其大概原理是建立一个和现有函数同名的函数(固然首先要把原来的函数给保存下来),以覆盖掉他本来的引用,而后在函数体内先针对参数作一些本身想要实现的功能,最后再调用以前保存的原函数,实现本来的功能。
这个思路也很像redux里面有关于middleware的设计,只不过redux运用的思想更为先进,经过一系列结构将各个中间件解耦,互不干扰。而本文的目的不是为了灵活的使用各类中间件,只是为了想作一个调试信息的自主整合页面,因此使用这种强联系的耦合方式也没有什么大问题。web
原文中的关键源码以下:ajax
window.console = { wc: window.console }; //将本来console的引用指向console的一个成员变量wc,以便在后面扩充的函数中使用。 var self = this; //保存当前语境中的this ['log', 'error', 'warn', 'debug', 'info'].forEach(function (item) { //针对console的五种方法 console[item] = function (msg) { this.wc[item](msg); self.log(msg, item); } });
代码选自原网页,注释是我加的。chrome
在JavaScript中,函数也是对象的一种,也能像对象同样拥有本身的变量。因此程序的前三行就是讲console这个对象换了一个别名wc保存在console自己内。
第四行是为了保存当前语境下的this,事实上在浏览器的调试工具中直接运行这些代码的时候,这个this指向的就是全局对象window,因此去掉这一行,将下面的self.log改为window.log,程序的运行结果是如出一辙的。
保存完了全部须要的变量后,下面的事情就简单了,遍历console下的log, error, warn, debug和info这五个方法,把他们都修改为先执行自己,而后再执行咱们自定义的log方法,在这个自定义的log方法内,咱们能访问到传入的参数msg和访问的原生函数名item,而后就能够经过这个钩子,去获取数据,并作一些处理,显示到AlloyLever的控制台上啦。json
而ajax的截获跟这个原理也差很少,代码以下:redux
var XHR = window.XMLHttpRequest; window.XMLHttpRequest=function(){ var xhr = new XHR(); checkSuccess(xhr); return xhr; }; window.XMLHttpRequest.realXHR = XHR; var self=this; function checkSuccess(xhr) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { self.option.xhrs.push({url:xhr.responseURL, json:JSON.stringify(JSON.parse( xhr.responseText), null, "\t")}) }else if(xhr.status>=400) { console.error(xhr.responseURL +' '+xhr.status+' ('+xhr.statusText+')') } else{ window.setTimeout(function () { checkSuccess(xhr); }, 0); } }
区别就是由于ajax是异步请求,因此在函数内部内置了一个setTimeout循环,若是请求未完成则一直循环,直到请求完成,内容被捕获为止。segmentfault
这个工具还有个移动端的版本:https://github.com/WechatFE/v...
对于作微信开发的小伙伴们,之后的测试就方便多啦!浏览器