vConsole源码阅读报告

vConsole解决的三个关键问题

  1. 如何捕捉错误
  2. 如何输出循环定义对象
  3. 如何捕捉ajax请求

如何捕捉错误

使用window.onerror = function(message, source, lineno, colno, error) { ... }来捕捉JavaScript运行时错误(包括语法错误)。

以下信息来自MDN

函数参数为:  
- message:错误信息(字符串)。Available as event (sic!) in HTML onerror="" handler.
- source:发生错误的脚本URL(字符串)
- lineno:发生错误的行号(数字)
- colno:发生错误的列号(数字)
- error:Error对象(对象)  
若该函数返回true,则阻止执行默认事件处理函数。 

跨域脚本的错误捕捉

对跨域脚本需加crossorigin属性,比如这个样子<script crossorigin />
然后对js文件添加跨域header属性,比如这个样子Access-Control-Allow-Origin: *添加方法点我

如何输出循环定义对象

循环定义的对象输出,原生APIJSON.Stringify()会报错,报错信息为Uncaught TypeError: Converting circular structure to JSON
判断对象是否循环定义的思路是,子节点的引用跟其祖先的引用相同。
参考vConsoletool.jsJSONStringify方法。

如何捕捉ajax请求

最基本的ajax代码如下:

var httpRequest = null;
httpRequest = new XMLHttpRequest();
httpRequest.overrideMimeType('text/json');
httpRequest.onreadystatechange = function(){
  /*
  0 UNSENT (未打开)    open()方法还未被调用.
  1 OPENED  (未发送)   send()方法还未被调用.
  2 HEADERS_RECEIVED (已获取响应头)   send()方法已经被调用, 响应头和响应状态已经返回.
  3 LOADING (正在下载响应体)   响应体下载中; responseText中已经获取了部分数据.
  4 DONE (请求完成) 整个请求过程已经完毕.
  */
  if (httpRequest.readyState == 4) {
    // 200(OK)
    // 404(Not Found) or 500(Internal Error)
    if (httpRequest.status == 200) { 
      var responseText = httpRequest.responseText;

    } else {
      
    }
  } else {

  }
};
httpRequest.open('GET', 'xxx.json', true);
httpRequest.send(null);

这里涉及到ajax相关信息有,请求地址(url),请求方法(method),请求参数,请求状态,请求时间,请求Headers信息,响应内容。
获取上述信息的途径有:

  • window.XMLHttpRequest.prototype.open方法中可以获取到请求地址(url),请求方法(method)信息。
  • window.XMLHttpRequest.prototype.send方法中可以获取到POST请求的请求参数信息。
    如果是GET请求,需对请求地址(url)的查询字符串进行解析处理。
  • window.XMLHttpRequest.prototype.status属性即为请求状态
  • 获取ajax请求所消耗时间,只需在onreadystatechange方法中的DONE阶段声明的时间 减去 在UNSENT阶段声明的时间即可。
  • 通过window.XMLHttpRequest.prototype.getAllResponseHeaders方法可获取到请求Headers信息
  • window.XMLHttpRequest.prototype.response属性即为响应内容
    根据响应内容的类型responseType的值text,json,blob,document,arraybuffer做对应的字符串格式化。

参考vConsolenewtwork.jsmockAjax方法。

其它

chrome跑example页面发现报Cannot read property 'trigger' of undefined错误。
原因是zepto.touch.min.js使用了pointer事件。
关于pointer事件,参考这个链接
pointer事件用来统一鼠标(mouse)、触摸屏(touch)、触控笔(pen)三者的交互事件。
chrome未完善支持,导致报错。

  1. 判断网页文档准备情况。
if (document !== undefined) {
  if (document.readyState == 'complete') {
    _onload();
  } else {
    $.bind(window, 'load', _onload);
  }
} else {
  // if document does not exist, wait for it
  let _timer;
  let _pollingDocument = function() {
    if (document && document.readyState == 'complete') {
      _timer && clearTimeout(_timer);
      _onload();
    } else {
      _timer = setTimeout(_pollingDocument, 1);
    }
  };
  _timer = setTimeout(_pollingDocument, 1);
}

可参考这个链接

render panel DOM
把core.html里面的节点渲染到页面上。
这里有个element.insertAdjacentElement方法,详细参考此链接

log输出三种形式,如果是function,直接通过其toString方法输出。如果是字符串,需经过htmlEncode后输出。
如果是对象或者数组。
首先输出类型名称和预览(少于26个字符)
遍历对象下属的key和对应的vlaue,value类型。
获取对象的prototype nameObject.prototype.toString.call(obj).replace('[object ', '').replace(']', '');

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 五十三:请解释 JavaScript 中 this 是如何工作的。1.方法调用模式当一个函数被保存为一个对象的属性...
    Arno_z阅读 613评论 0 2
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,944评论 2 17
  • 为啥总是要吐槽他人的闲话? 1、她是个爱讲闲话的人,如果对于她每说的一句闲话,我都评价,那我岂不是成为跟她一样爱讲...
    不断变强的兔子阅读 296评论 0 0
  • 有个朋友很奇怪,说自己从入职开始,自己的经理就不喜欢自己,事情一直需要自己做,任务也给安排的很重,但是一直对自己就...
    范先生说阅读 921评论 0 0
  • 在辅导班里看见的这本书,被名字吸引,就拿过来看,是加里格卡夫曼的自传。不知道以前看谁说过一句话,要看书就要看自传而...
    红豆抹茶味儿阅读 100评论 0 0