Javascript:调试eval()和new Function()创建的代码
我试图将一个私有变量放入一个已经存在的函数中,例如:Javascript:调试eval()和new Function()创建的代码,javascript,debugging,eval,private-members,Javascript,Debugging,Eval,Private Members,我试图将一个私有变量放入一个已经存在的函数中,例如: 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");
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()函数,该函数由一个存在的AOObject拥有,并带有私有变量。。。我使用eval(或new函数)获取它,但不幸的是调试器将被破坏
因此,有一种方法可以不使用eval来实现这一点,或者有一种方法可以使用eval并使调试器保持有用?我认为如果希望局部变量
a
在克隆函数中可用,那么使用eval
是唯一的选择。另外,如果希望局部变量a
在克隆函数中可用,我会尝试另一种调试器(Firefox上的Firebug?我认为使用eval
是唯一的选择。另外,我会尝试另一个调试器(Firefox上的Firebug?调试器没有指向函数中的行的原因是,您正在调用的函数与AObject.get
函数根本不相关(就JavaScript而言)。Eval无法知道定义函数的字符串来自何处。调试器应该指向调用eval的那一行,因为函数是在这一行定义的,但它显然偏离了一行
为了回答您的问题,我认为没有办法避免eval(或函数,这可能更可取),除非您可以将函数定义移动到
temp
中,使其关闭“a”或向get
函数添加“a”参数。调试器没有指向函数中的行的原因,您正在调用的函数与AObject.get
函数根本不相关(就JavaScript而言)。Eval无法知道定义函数的字符串来自何处。调试器应该指向调用eval的那一行,因为函数是在这一行定义的,但它显然偏离了一行
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();
为了回答您的问题,我认为没有办法避免eval(或函数,这可能更可取),除非您可以将函数定义移到temp
中,使其关闭“a”,或将“a”参数添加到get
函数中。@svinto
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();
你现在明白了吗?@svinto
你现在明白了吗?你想做这样的事吗
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 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那样在函数中传递此变量
编辑:删除了错误的代码。@kentaromiura
不,您的方法只适用于将变量放入窗口范围(全局…)
您的“this”键是“window”对象,因此
this.a="A"
就像你做的一样
window["a"]="A"
这样就成为一个全球性的var
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
这不是一个解决方案,必须是私有的,而不是全局的。
如果我决定使用全局变量,我将开始使用一个全局向量来存储我的私有变量。
谢谢。@kentaromiura
不,您的方法只适用于将变量放入窗口范围(全局…)
您的“this”键是“window”对象,因此
this.a="A"
就像你做的一样
window["a"]="A"
这样就成为一个全球性的var
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
这不是一个解决方案,必须是私有的,而不是全局的。
如果我决定使用全局变量,我将开始使用一个全局向量来存储我的私有变量。
谢谢。是的,我使用firebug,错误标记在错误的行中。是的,我使用firebug,错误标记在错误的行中。嗯。。。很明显,我不能这样做,对象已经存在,或者简单地说,我的情况是:temp({get:function(s){returns s.toLowerCase()+a;}})@我不明白你的意思。嗯。。。很明显,我不能这样做,对象已经存在,或者简单地说,我的情况是:temp({get:function(s){returns s.toLowerCase()+a;}})@我不明白你的意思。必须是私有变量,此关键字无法访问。请原谅我的问题,但为什么?如果你有一个私有变量,你必须传递这个变量,唯一的方法或者,根据你真正想要的,另一种方法是对一个对象应用/调用一个方法;我的班级必须有私人成员。Eval运行良好,只是它破坏了调试器。必须是私有变量,此关键字无法访问。请原谅我的问题,但为什么?如果你有一个私有变量,你必须传递这个变量,唯一的方法或者,根据你真正想要的,另一种方法是对一个对象应用/调用一个方法;我的班级必须有私人成员。Eval运行良好,只是它破坏了调试器。为什么不使用公共istance变量?它总是比使用未声明的全局变量编写方法要好…为什么不使用公共istance变量?它总是比使用未声明的全局。。。