前面有帖子说到在函数里如何能在全局空间上eval
。 虽然此种需求在绝大多数情况下是不合理的,但是仍有极少数情况可能确实有需要。
JScript有execScript方法可以用来执行脚本。其第一个参数为代码字符串,第二个参数为脚本语言,可以选择jscript或者vbscript。
而在其他脚本引擎中,SpiderMonkey保留了JS最早时候的在对象上的eval方法。也就是在任何对象上,都可以eval,执行时,会把该对象加入scope chain。
例如 {x:1}.eval('x')会返回1,而(o={x:2}).eval('var x = 10')后o.x会等于10。
基本上 o.eval(code); 类似于with (o) { eval(code) }。
唯一值得注意的是var x这样的语句。对于
var o = {x:1};
with(o) {
var x = 2;
}
Safari(JavaScriptCore和KJS引擎)会产生一个全局的x变量。除此之外(JScript、SpiderMonkey、Opera、Rhino等),都会令o.x = 10。注意:前提条件是o上面已经有x属性。
由SpiderMonkey所具有的Object.eval方法,我们可以知道,在Firefox中,window.eval()与直接eval()的效果是不同的。前者的效果接近execScript。
【2008年7月6日更新:afcn0同志指出,根据https://bugzilla.mozilla.org/show_bug.cgi?id=382509
,该方法已经在1.8.1.13(Firefox 2.0.0.13)去除。】
其他引擎不支持Object.eval,但是Opera把window.eval作为一个特例,与Firefox的效果是一样的。除了Safari以外,我们也可以用with(window) {eval(...)}来模拟execScript,但前提是你知道所有在global上声明的var的名字,并预先在window上创建这些变量——多数情况下这不太实际。
SpiderMonkey的eval还可以传第二个参数,eval(code, o)基本等价于o.eval(code),但是两者还是有微妙的差别。如
var a = 'global';
var code = 'alert(a)';
var context = (function () { return function a() {} })();
context.eval('alert(a)');
eval('alert(a)', context);
这两次返回的值是不同的。在eval(code, o)的时候,会继续从o.__parent__(即[[scope]])开始寻找。而函数表达式的名字,或者函数外部的with语句,都会给其[[scope]]增加一层对象。
关于new Function(code),实际上PIES就是使用的这个方法来生成代码而不是像其他一些框架那样使用eval。另外我还用它来做对模板的“编译”。使用Function比eval要好很多。因为它总是在一个新的execution context上,从而避免了许多eval可能出现的bug(早期版本的浏览器经常在某些特殊eval时崩溃)。所以如果需要生成代码,应优先使用new Function。
但是new Function对于需要执行var x=1,把x放到global的需求,是不合适的。虽然这种需求非常罕见(以至于多数情况下这种需求是错误的需求),但因为本文恰恰是说这个问题,因此就略过。
事实上,对于SpiderMonkey和Rhino来说,还有另一个方法,也是推荐的方法,那就是使用Script方法。Script(code)的结果是一个函数,可以直接调用。例如Script('var a = 1')(),无论在哪里执行,都会在global上产生a变量。实际上Script结果的调用就是对Script.prototype.exec的调用。Script.exec,基本上是execScript的真正对应。注意,Rhino上必须直接调用而不能用Script(code).exec()调用。SpiderMonkey上Script.exec可以带有参数,如果带有参数obj,效果就跟eval(code, obj)接近。
好,最后总结一下:
JScript上使用execScript(code)
SpiderMonkey和Rhino上可使用Script(code)()
Opera下使用window.eval(code)
唯一的问题是Safari。实际上window.eval已经被作为一个bug被提交并且fixed了(参考http://trac.webkit.org/projects/webkit/changeset/25535
),我们希望下一个版本的Safari应该就可以与Opera一样,使用window.eval了。
分享到:
相关推荐
2. 使用`window.eval()`:在某些情况下,如果必须使用`eval()`,可以将它限制在全局作用域,通过`window.eval()`调用,这样Closure Compiler可以识别这是一个全局操作。 3. 使用`@nocache`注释:在`eval()`前添加`/...
这里需要注意的是,虽然`X2.Eval`内部也使用了`eval`,但由于它是通过`window.eval`调用的,所以它仍然会在当前作用域内执行。 #### 六、总结 尽管`eval`函数提供了强大的功能,但鉴于其可能带来的安全性和性能...
### JavaScript中的`eval`与`with`用法详解 #### 一、`eval`函数 ##### 1. 定义 `eval`是JavaScript中一个非常强大的内置函数,它可以将字符串解析并执行为JavaScript代码。这使得开发者能够在运行时动态地创建和...
根据给定的信息,我们可以归纳总结出以下几个重要的知识...以上是基于提供的部分代码内容总结的ASP中JavaScript的使用方法及相关知识点,这些方法可以帮助开发者更好地在ASP页面中嵌入和使用JavaScript来增强用户体验。
这里的代码利用了`ExternalInterface.call`方法调用了JavaScript中的`eval`函数来执行`window.location.href`,从而获取到了完整的URL。 ##### 2. 获取协议 协议可以通过`window.location.protocol`来获取。例如:...
JavaScript 的 `eval` 函数是一个强大且复杂的工具,主要用于将字符串转化为可执行的 ...对于在函数内部执行全局代码,可以利用浏览器的特定方法,如 `execScript` 和 `window.eval`,但也要注意浏览器兼容性问题。
根据提供的文件信息,我们可以分析出该文件主要涉及的是HTML与JavaScript相关的知识点,特别是与`<iframe>`元素以及JavaScript中的`eval()`函数的应用有关。接下来,我们将深入探讨这些知识点。 ### ...
IE中,`window.event`对象用于访问当前事件的相关信息,但在Firefox中,事件信息是通过事件处理函数的参数传递的。要兼容两者,可以在事件处理函数中检查`event`参数,如果没有,则从`window`对象中获取: ```...
根据提供的信息,我们可以总结出以下ASP.NET相关的知识点: ### ASP.NET 实用代码示例与解析 #### 1. 显示提示并跳转页面 ```csharp // 显示提示信息并进行页面跳转 CODE: Response.Write("<script>window.alert...
为了兼容不同浏览器,可能需要使用window.eval()方法,或者在IE中使用window.execScript()。例如: ```javascript if (window.execScript) { window.execScript("var x = 1;"); } else { window.eval("var x = 1;...
Response.Write("<script>window.alert('该会员没有提交申请,请重新提交!')</script>"); Response.Write("<script>window.location ='http://www.51aspx.com/bizpulic/upmeb.aspx'</script>"); 该语句用于弹出一...
此函数通过`window.open`方法打开一个新的浏览器窗口,其中`pic_all.aspx`页面将根据传入的ID参数加载具体的图片信息。 3. **自适应窗口大小** 为了使`pic_all.aspx`页面能够根据图片大小自动调整窗口尺寸,需要...
3. **自定义属性**:IE允许通过常规属性方法或`getAttribute()`获取自定义属性,而FF仅支持`getAttribute()`。为了兼容,应始终使用`getAttribute()`。 4. **ID查找**:IE下可以用`eval("idName")`或`...
这段代码仅在IE浏览器下有效,利用`window.external.AddFavorite`方法可以将指定的网址添加到用户的收藏夹中。 ##### 方法二:兼容多种浏览器的添加收藏夹功能 ```javascript function addFavorite(url, title) { ...
在Silverlight中,我们可以使用`HtmlPage.Window.Eval()`方法执行JavaScript代码。例如,如果你想改变一个HTML元素的文本,可以在Silverlight中编写如下代码: ```csharp HtmlPage.Window.Eval("document....
ASP.NET提供了强大的数据绑定功能,可以直接在数据模板中使用`DataBinder.Eval`方法来访问数据项的属性,并使用`DateTime`类的`ToShortDateString`方法来格式化日期。 ```csharp <%# System.DateTime.Parse...
- `eval("window.j=0")`: 使用 `eval()` 函数来动态执行字符串作为 JavaScript 代码。虽然这种方式可以实现动态变量声明,但在实际开发中不推荐使用,因为它可能会导致安全问题和代码可读性差的问题。 - 其他类似的...
- 解决方法:使用`document.getElementById(idName)`代替`eval(idName)`。 6. **变量名与HTML对象id相同的问题** - 问题描述:在Firefox中,可以使用与HTML对象id相同的变量名,但IE不允许。 - 解决方法:始终在...
- 用`eval("idName")`在IE中获取ID为"idName"的对象,但Firefox不支持。推荐使用`document.getElementById("idName")`。 8. 变量名与HTML对象ID相同: - 在Firefox中,变量名不会覆盖HTML对象ID,但在IE中可能会...