• 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的源代码 


  • 相关阅读:
    JavaScript 23 Window
    JavaScript 22 自定义对象
    JavaScript 21 Math
    History 7 : Christianity, Science, and The Enlightenment
    History : The Atlantic Slave Trade
    History 6 : Aztec and Inca Empires / African empires 8001500
    003 几个python编程例子
    006 网络的瓶颈效应
    0212 Logistic(逻辑)回归
    002 用Python打印九九乘法表与金字塔(*)星号
  • 原文地址:https://www.cnblogs.com/gdutbean/p/2352590.html
Copyright © 2020-2023  润新知