【问题标题】:Javascript: Debuging code created by eval() and new Function()Javascript:由 eval() 和 new Function() 创建的调试代码
【发布时间】:2009-09-28 15:25:13
【问题描述】:

我正在尝试将一个私有变量放入一个已经存在的函数中,例如:

var AObject={
 get:function(s){
        return s.toLowerCase()+a;
    }    
}

function temp(){
    var a="A";
    var o={};
    eval("o.get="+AObject.get.toString());
    reurn o;
}

var bObject=temp();
BObject.get("B");    // "bA"
BObject.get();  /* error: s is undefined; but marked in line "return o;"
                    and not in "return s.toLowerCase()+a;"*/

我的目标是运行 get() 函数,由现有的 AObject 拥有,使用私有 var ...我使用 eval(或 new 函数)获得它,但不幸的是调试器将被破坏!

那么,有没有一种方法可以在不使用 eval 的情况下实现这一点,或者有一种方法可以使用 eval 并保持调试器有用?

【问题讨论】:

    标签: javascript debugging eval private-members


    【解决方案1】:

    调试器未指向函数中的行的原因是,您正在调用的函数与AObject.get 函数完全不相关(就 JavaScript 而言)。 eval 无法知道定义函数的字符串来自哪里。调试器应该指向你调用 eval 的那一行,因为那是定义函数的地方,但它显然被一行所取代。

    要回答您的问题,我认为没有办法避免 eval(或 Function,这可能会更可取),除非您可以将函数定义移动到 temp 中,使其关闭“a”或添加get 函数的“a”参数。

    【讨论】:

      【解决方案2】:

      如果您希望局部变量 a 在克隆函数中可用,我认为使用 eval 是您唯一的选择。另外,我会尝试不同的调试器(Firefox 上的 Firebug?)

      【讨论】:

      • 是的,我正在使用firebug,错误标记在错误的行中。
      【解决方案3】:
      function objectbuilder(a){
        return {
          get:function(s){
            return s.toLowerCase() + a;
          }
        };
      }
      
      function temp(){
        return objectBuilder("A");
      }
      
      var bObject=temp();
      BObject.get("B");    // "bA"
      BObject.get();
      

      【讨论】:

      • ehm... 显然我不能这样做,对象已经存在,或者简单地说,我有 ti 情况: temp({ get:function(s){ return s. toLowerCase() + a; } });
      • @blow:我不明白你的意思。
      【解决方案4】:

      @svinto

      function temp(obj){
          var a="A";
          var o={};
          eval("o.get="+obj.get.toString());
          reurn o;
      }
      
      var myObj=temp({
          get:function(s){
              return s.toLowerCase()+a;
          }
      });
      
      myObject.get("B");   //bA
      

      你现在明白了吗?

      【讨论】:

        【解决方案5】:

        @kentaromiura

        不,您的方式仅适用于您将变量放在窗口范围内(全局...)

        你的“this”键是“window”对象,所以当你这样做时

        this.a="A"
        

        就像做事

        window["a"]="A"
        

        这样就变成了全局变量

        function temp(obj){
            var a="A";
        
            return (function(){
                this.a =a;
                var o={};    
                o.get=function(s){return obj.get.call(this,s)};    
                return o;
            })();
        
        }
        
        var myObject=temp({
            get:function(s){
                return s.toLowerCase()+a;
            }
        });
        
        alert(myObject.get("B"));   //bA
        alert(a); //A
        

        这不是解决方法,必须是私有的,而不是全局的。 如果我决定使用全局变量,我将开始使用全局向量,我可以在其中存储我的私有变量。 谢谢。

        【讨论】:

        • 你为什么不使用 public istance 变量?它总是比使用未声明的全局编写方法更好......
        【解决方案6】:

        你是在尝试做这样的事情吗???

        var AObject={
         get:function(s){
                return s.toLowerCase()+this.a;
            }    
        }
        
        function temp(){
        
            return {get:function(s){return AObject.get.call({a:"A"},s);}};
        
        }
        

        编辑:在他的评​​论之后;

        你知道吗,你会做的事情是非常错误的,它只是因为 eval 改变了作用域链,基本上你正在这样做:

        function temp(obj){
            var a="A";
            var o={};
        
            o.get=function(s){
                    return s.toLowerCase()+a;
            }
        
            return o;
        }
        

        由于 a 在闭包中,这将起作用,但您没有调用真正的 obj get 函数,而是创建了另一个在 temp 中工作的函数;

        但是,正如我在评论中所说,你不应该编写包含未声明变量的函数,而应该像 svinto 那样在函数中传递这个变量。

        编辑:删除了错误的代码。

        【讨论】:

        • 请问这个问题,但是为什么?如果你有一个私有 var,你必须传递这个 var,这是唯一的方法,或者,根据你真正想要什么,另一种方法是在对象上应用/调用方法。跨度>
        • 我正在寻找一种通过将对象作为参数传递来构建类的方法;我的班级必须拥有私人成员。 eval 效果很好,只是它破坏了调试器。
        猜你喜欢
        • 2011-06-03
        • 2015-07-30
        • 2019-11-03
        • 1970-01-01
        • 1970-01-01
        • 2011-12-31
        • 1970-01-01
        • 2014-07-17
        • 1970-01-01
        相关资源
        最近更新 更多