javascript调试原理(三) (转)

JavaScriptjavascript调试原理(二)中给出一个模拟客户端调试的例子,在客户端有两个问题: 
1.如何获得当前的context? 
2.如何做resume,stepinto,stepreturn,stepover? 
本章围绕着这两个问题展开讨论 
1.如何获得当前的context 
我们先看一段代码: 

Java代码  收藏代码
  1. function test(){  
  2.     this.a = "a";  
  3.     var b = "b";  
  4. }  


那么在进入test之后,如何获得a和b的值呢? 
a的值比较简单,只要把this传过去,通过for...in语句就可以获得,但是b呢?它相当于一个私有变量,在外面是不能访问的,要访问b只能通过在b所在的作用域中获得,因此我们在插入前面的每一行中要加上一个eval函数,eval函数的作用域是当前行的,所以可以获得当前行的上下文。所以在第二章中才会在每一行加上 

Java代码  收藏代码
  1. function(text){try{return eval(text)}catch(e){}});  


我们把a,b,c加上看一下效果 

Java代码  收藏代码
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">  
  2. <HTML>  
  3. <HEAD>  
  4. <TITLE> New Document </TITLE>  
  5. <META NAME="Generator" CONTENT="EditPlus">  
  6. <META NAME="Author" CONTENT="">  
  7. <META NAME="Keywords" CONTENT="">  
  8. <META NAME="Description" CONTENT="">  
  9. </HEAD>  
  10.   
  11. <BODY>  
  12. <textarea id="jsstr" readonly style="400px;height:200px">function test(){  
  13.     var a = test1();  
  14.     var b = test2();  
  15.     var c = "result is " + a + b;  
  16.     alert(c);  
  17. }  
  18. function test1(){  
  19.     return "test1-->abc";  
  20. }  
  21. function test2(){  
  22.     return "test2-->abc";  
  23. }  
  24. test();</textarea>  
  25. <div id="result">  
  26.       
  27. </div>  
  28. <script>  
  29. var debugStr = "";  
  30. function jsdebug(resource,line,evalFunc){  
  31.     var lines = debugStr.split("\n");  
  32.     var jsLine = lines[line-1];  
  33.     lines[line-1] = "当前行:--->" + jsLine;  
  34.     var arr = [  
  35.         "调试代码:",  
  36.         lines.join("\n"),  
  37.         "==========context===========",  
  38.         "a = " + evalFunc("a"),  
  39.         "b = " + evalFunc("b"),  
  40.         "c = " + evalFunc("c"),  
  41.     ];  
  42.     var result = document.getElementById("result");  
  43.     result.innerHTML = result.innerHTML + "<br>执行到第" + line + "行: -->" + jsLine;  
  44.     alert(arr.join("\n"));  
  45.   
  46. }  
  47. function debug(str){  
  48.     var lines = str.split("\n");  
  49.     debugStr = str;  
  50.     var codes = [];  
  51.     for(var i=0;i<lines.length;i++){  
  52.         codes[i] = "jsdebug('test'," + (i+1) + ",function(text){try{return eval(text)}catch(e){}});" + lines[i];  
  53.     }  
  54.     eval(codes.join('\n'));  
  55. }  
  56. debug(document.getElementById('jsstr').value);  
  57. </script>  
  58. </BODY>  
  59. </HTML>  


在执行到第3,4,5行的时候可以看到a,b,c的值 
这里又有一个问题:我怎么知道函数中有哪些变量? 
这就要用到arguments.callee.caller了,把函数当成一个字条串解析,解析出函数的输入参数及定义的变量,就能拿到一个变量名的集合,然后再一个一个地取值。具体的算法这里就不给出了。 

再说第二个问题,如何控制stepinto,stepreturn,resume 
我们需要在客户端维护一个函数的调用栈,这个栈中记录着每一步的调用,在执行的时候根据栈中存的信息和当前的上下文比较,就能拿到当前语句究竟是stepover还是stepinto还是stepreturn。 

那么如何做resume呢,客户端维护一份断点列表,执行每一句的时候判断是否到了断点,不在断点就继续执行,到了断点就停止。 

这部分内容也不再给出详细代码,请参照Javascript Debug Toolkit的源代码 


原文地址:https://www.cnblogs.com/gdutbean/p/2352590.html