1

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

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 Function)获得它,但不幸的是调试器将被破坏!

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

4

6 回答 6

1

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

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

于 2009-09-28T16:57:07.183 回答
0

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

于 2009-09-28T16:04:53.270 回答
0

@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

你现在明白了吗?

于 2009-09-29T08:23:58.730 回答
0
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();
于 2009-09-28T17:10:52.343 回答
0

@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

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

于 2009-09-29T17:00:28.637 回答
0

你想做这样的事情吗???

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 那样在函数中传递这个变量。

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

于 2009-09-29T08:59:00.577 回答