2012-05-09 121 views
2

我正在调试和升级一些遗留的PHP和JavaScript代码,并且发现了一些我无法摆脱的eval()函数。来自桌面编程环境,编译语言如C/C++我从来没有在javascript中使用eval()函数,主要是因为我不知道它的存在。我一直在使用Google,并从所有我读过的内容中了解到,eval()会评估字符串,就像它是合法的JavaScript代码并执行它一样。我已经设法摆脱了用于访问动态属性和解码JSON对象的eval()函数,但是有一个相当先进(和模糊)的类定义,它使用了eval(),我没有能够击败。eval()和全局范围

样品的编号:

function Ddl(N) { 
    this.lyr = document.getElementById(N); 
    this.obj = N+"DDL_Lyr"; 
    eval(this.obj+"=this"); 
    this.lyr.setAttribute("onchange", this.obj+".onChange();"); 
} 

此函数是一个对象的构造。 DDL对象在网页中使用:

ddl_name = new Ddl('id_of_select'); 
ddl_name.onChange = event_function; 

对于这一切,我知道,eval(this.obj + "=this")应该是一样的this.obj = this;但随后onchange事件功能event_function不被解雇。我一直无法猜测为什么使用萤火虫。如果我使用this.obj = this,我可以看到this.obj的值从id_of_selectDDL_Lyr更改为一个指向DDL对象的指针,所以我可以确定setAttribute失败的原因,但是使用eval()函数this.obj并不会将代码反映为代码被执行,它始终保持为'id_of_selectDDL_Lyr',但它的做法是,因为如果我将它注释掉,onchange事件不会被触发。

我怀疑它可能与本地或全局范围有关,因为我读过eval()调用在不同的范围内执行,但我不知道如何删除它,也不知道如何替换eval ()与正常的JavaScript代码。

+0

看起来像某种形式的对象的与平变化的另外的结合克隆event.Take看看这个讨论:http://stackoverflow.com/问题/ 122102 /什么是最有效的方法克隆一个JavaScript对象 – primavera133

+0

你试过'this.obj = window'吗?如果你的'onChange()'函数在全局范围内,你不需要btw。 –

+0

据我所见,eval可以用'window [this.obj] = this'替换,但我建议你先用console.log先记录一些示例数据,以确认没有意外的行为。 – scragar

回答

1

认为这个代码是等价的:

function Ddl(N) { 
    var self = this; 
    this.lyr = document.getElementById(N); 
    this.obj = N + "DDL_Lyr"; 
    window[this.obj] = this; 
    this.lyr.onchange = function() { 
     self.onChange(); 
    }; 
} 

eval没有说this.obj = this,它创建一个新的全球变量与 “N + DDL_Lyr”(其中N是可变的)。

+0

只有当'this.obj'中的字符串值与全局范围中的变量名称相同时,这才相当...该变量可能位于不是全局范围的外部范围中。 –

+0

@GGG它_could_,但我不认为它是,在这种情况下。 – Alnitak

+0

我也不这么认为,但OP应该确定。 –

-1

变化

this.lyr.setAttribute("onchange", this.obj+".onChange();"); 

this.lyr.onchange = this.obj+".onChange();"; 
+2

AFAIK不起作用 - 设置'onchange'属性时,您必须提供函数引用,而不是字符串。 – Alnitak