`
wezly
  • 浏览: 484653 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

让eval()在全局作用域中执行的方法

阅读更多

    eval(str) 用来传入一个字符串动态执行一段脚本,这个方法非常有用。当直接用eval()时,作用域为当前作用域,有时候我们需要让它在全局作用域范围内执行,比如 ajax返回的脚本字符串,然而浏览器对eval的差异可能使事情刚开始并不是那么顺利,本文通过在7种浏览器(IE, Firefox, Chrome, Safari, Opera)环境中测试,并提出三种解决方案,使这个问题比较完美的解决。

 

看这一段javascript代码:

function xx(){ 
    var x= 1 ; 
    window .eval( 'var x=3;' ); 
    document .writeln(x); 
}

xx();

在你自己测试和看我接下来的分析之前,先想想,你认为输出结果会是什么呢?是1还是3?

根据本文的标题,可知肯定是在不同浏览器下有不同表现的。

以下是我的实测数据:

JS代码 浏览器 版本 运行结果
function xx(){ 
    var x= 1 ; 
    window .eval ( 'var x=3;' ); 
    document .writeln (x); 
} 
xx();
IE IE Firefox Chrome Chrome Safari Opera
7.0 8.0 3.0.8 1.0 4.0 4.0.2 9.62
3 3 1 3 1 1 1

 

可见各浏览器及版本对window.eval()的作用域处理是有差异的。

IE中,window.eval()和eval()一样只在当前作用域生效。

Firefox,Safari,Opera中,直接调用eval()为当前作用域,window.eval()调用为全局作用域。

尤其值得注意的是,Google Chrome 的不同版本之间对于eval的处理也有差异。

 

 

如果需要在全局作用域eval()的效果,且通用于所有浏览器,那就得好好变通一下了。

 

方法之一:

使用IE专有的window .execScript 。

如果你碰到这个问题不知所措,并上网搜索,这个方法大概是最先也几乎唯一能搜索到的方法。

window .execScript (sExpression sLanguage )。

比如上面那一段代码中eval一句如果换成window .execScript( 'var x=3;' ); IE中的运行结果就是1了。

非IE内核的浏览器并不支持window .execScript 。

IE之所以有这个window .execScript ,还和IE能够执行其他语言的脚本有关,通过给不同的sLanguage 参数,IE这个方法除能够执行javascript之外,还可以执行vbscript或是其他任何安装过相应解释引擎的脚本如perl,python等。

 

当需要在局部环境中执行的时候,我们就直接用eval()。

当需要在全局环境中执行的时候,我们可以封装一个通用的函数,就像下面这样:

 

//在全局环境中执行

function  evalGlobal(strScript){
    if(
 window .execScript) window .execScript( strScript );

    else window . eval ( strScript ); 
}

就是将IE和非IE区别开来对待。

看起来,问题似乎圆满解决了。但是显然是有问题的,比如上表中的Chrome 1.0也和IE的eval()规则一致,况且还不知道其他浏览器其他版本是否有差异呢,因此,这种方法并不很可靠。

 

但是如果你有一点完美主义者的倾向,那么事情还不能到此为止,肯定是有更好更简洁的方法的嘛。

不知道阅读此文的你是否有想到呢?

是否和我的想法一致呢?

 

方法之二:

新建一个<script>元素装载脚本。

这种方法常用来解决innerHTML中的脚本不能运行的问题。但用来解决eval()的作用域问题,恐怕就比较罕见了。

//在全局环境中执行

function  evalGlobal(strScript){

        var a = document .createElement ("script" );
        a.type= "text/javascript" ;
        a.text= strScript ;
        document .getElementsByTagName ("head" )[0 ].appendChild (a) ;
}

虽然这个方法有点变态,需要新增一个<script>元素,但优点是各种浏览器及版本通用,比方法一要好一些了。。

 

 

但是如果你有再多一点完美主义者的倾向,那么事情还不能到此为止,毕竟添加了一个HTML元素嘛,影响了页面原本的DOM结构。

那么是不是有更好更简洁的方法的呢?答案是肯定的。经过我的研究,找到了同时具备简洁和可靠的方法三。

不知道阅读此文的你是否有想到呢?

是否和我的想法一致呢?

 

方法之三:

还是eval。回归原生态。

我们别忘了javascript里面有一个改变上下文环境的关键字,强大的with .

原来事情可以更简单更有效!

//在全局环境中执行

function  evalGlobal(strScript){

        with ( window )eval (strScript) ;
}

看看,都这么简单了,我们完全可以不用封装为函数了,直接在代码中用。

 

文章最开始的代码我们就可以这样来了:

function xx(){ 
    eval ( 'var x=1;' );   //局部变量 
    with ( window ){ eval ( 'var x=3;' );}   //全局变量 
    //也可以用封装的 evalGlobal( 'var x=3' ); 
    document .writeln (x);   //1  局部变量 
    document .writeln ( window .x);   //3  全局变量 
} 
xx();

 

特别:

有时候,我们eval()要求既不是在全局执行,也不是在当前作用域执行,而是在父对象或子对象中执行,这时,用 with ( objContext )eval (strScript)就更加是不可替代的选择了。


 

总结:

让eval()全局作用域执行的方法主要有:

(1)window .execScript + window . eval    级别:弱。 缺点:不简洁,不可靠,不通用。

(2)document . createElement ("script" )    级别:凑合。缺点:不简洁,不干净。优点:可靠,通用。

(3)with ( objContext )eval (strScript)          级别:最佳。优点:简洁,干净,可靠,通用。

 

N整一个表格比较清楚:

让eval()全局作用域执行的方法 级别 缺点 优点
 (1)window .execScript + window . eval  弱  不简洁,不可靠,不通用  -
 (2)document . createElement ("script" )  凑合  不简洁,不干净  可靠,通用
 (3)with ( window )eval (strScript)  最佳  -  简洁,干净,可靠,通用

 

 

分享到:
评论

相关推荐

    javascript执行环境,作用域理解

    在 JavaScript 中,执行环境和作用域是两个非常重要和基本的概念,理解了这两个概念对于 JavaScript 中很多脚本的运行结果就能明白其中的道理了。执行环境是一个概念,一种机制,用来完成 JavaScript 运行时在作用域...

    javascript中eval函数用法分析.docx

    在这个例子中,`eval()`函数在全局作用域被调用,定义了全局变量`y`,并且可以在全局作用域中被访问。 #### 三、eval函数的执行上下文 `eval()`函数的执行上下文与调用它的上下文环境相同。这意味着: - **局部...

    作用域初理解1

    在查找变量时,引擎会从当前作用域开始,如果找不到,就向上级作用域查找,直到找到全局作用域。例如,如果在函数内部使用未声明的变量,会抛出`ReferenceError`;而在函数内部定义变量后,该变量仅在该函数作用域内...

    前端开源库-scope-eval

    全局作用域中的变量在整个脚本中都可访问,而函数作用域则限制了变量的范围,使其只在函数内部可见。`scope-eval`通过创建一个新的局部作用域,使得`eval`在执行时只能访问这个新作用域内的变量,从而避免了对全局...

    深入了解JavaScript,从作用域链开始(1).pdf

    在JavaScript中,有两种主要的作用域类型:全局作用域和局部作用域。 全局作用域指的是在代码的任何位置都可以访问的变量或函数。这种作用域通常适用于在脚本或函数外部定义的变量和函数。例如,如果在函数外部使用...

    javascript执行环境及作用域详解_.docx

    - 在执行阶段: - 当`A`被调用时,首先创建`A`的活动对象,并将其压入执行环境栈。 - 如果`B`被调用,也会创建`B`的活动对象,并将其压入执行环境栈。`B`的`[[scopechain]]`中包含了`A`的活动对象以及全局对象。 ...

    测试eval方法所以造成无法通过google closure compiler编译

    2. 使用`window.eval()`:在某些情况下,如果必须使用`eval()`,可以将它限制在全局作用域,通过`window.eval()`调用,这样Closure Compiler可以识别这是一个全局操作。 3. 使用`@nocache`注释:在`eval()`前添加`/...

    javascript执行环境及作用域详解

    JavaScript执行环境及作用域详解: JavaScript的执行环境和作用域是理解这门语言核心概念的关键部分,它影响着变量...执行环境定义了代码的执行上下文,而作用域则决定了变量和函数如何在不同的上下文中被访问和操作。

    eval函数的一些用法

    值得注意的是,`eval`在不同作用域下有不同的行为:如果在全局作用域中,它可以访问和修改全局变量;而在函数作用域中,它通常只能访问局部变量(除非使用`var`声明)。 四、安全问题 `eval()`的主要危险在于它...

    深入认识javascript中得eval函数

    3. **作用域问题**:`eval`在全局作用域或调用它的函数的作用域中执行代码。这意味着`eval`内部可以访问外部变量,也可能修改它们。这可能导致难以追踪的副作用和调试困难。 #### 四、eval函数在实际开发中的应用 ...

    定义全局对象文章代码

    总结起来,全局对象在JavaScript和V8引擎中占据着核心地位,它不仅提供了变量和函数的全局作用域,还参与到内存管理、优化编译和模块交互等多个层面。理解全局对象的运作原理对于编写高效、可维护的JavaScript代码至...

    CSHARP_EVAL_FUNCTION

    另外,如果你需要在特定的上下文中执行代码(例如,访问类成员或变量),那么你可能需要使用`ScriptRuntime`和`ScriptEngine`,并传递适当的全局作用域和上下文对象。 总的来说,虽然C#没有直接提供`eval()`这样的...

    05-python-修饰符的使用-operator模块-作用域-动态编译

    在Python中,主要有四种作用域:局部作用域(定义在函数内)、全局作用域(定义在模块级别)、嵌套作用域(定义在闭包内)和内置作用域(Python内置的变量)。`global`关键字用于在函数内引用全局变量,而`nonlocal`...

    delete-in-eval.rar_Able

    这些文件可能探讨了不同场景下`eval()`的使用,例如在全局作用域和局部作用域中,或者与闭包结合时的情况。 总的来说,理解如何在JavaScript中安全、有效地使用`eval()`和`delete`操作符是一项重要的技能。需要注意...

    eval与window.eval的差别分析

    在非IE浏览器(IE9及以后版本、Firefox、Safari、Chrome和Opera)中,`window.eval`始终在全局作用域中执行,无论它被调用的位置如何。这意味着它会改变全局变量`x`的值,即使在函数内部调用也是如此。而在IE6/7/8中...

    global-load-from-eval-in-with.rar_inside

    然而,在严格模式下,“eval”的行为有所不同,它不会在调用它的作用域中执行,而是创建一个新的独立的作用域。 压缩包内的两个文件名,15.9.3.8-4.js 和 global-load-from-eval-in-with.js,可能分别代表了两个...

    执行上下文1

    例如,当在全局作用域中调用`eval`声明了一个变量,这个变量在全局范围内是可见的;而在函数内部调用`eval`,变量则只限于该函数的作用域。 在SpiderMonkey引擎(Firefox和Thunderbird的一部分,自1.7版本起)中,...

    结合代码图文讲解JavaScript中的作用域与作用域链

    局部作用域中的变量和函数只在其定义的函数内部可访问。而全局作用域定义的变量和函数在程序的任何地方都能被访问。 例如,在给定的例1中,定义了一个全局变量scope,然后在函数fn内部访问这个变量两次。在第一次...

    深入认识javascript中的eval函数

    window.eval("alert('执行在全局作用域中');"); ``` 为了兼容不同浏览器,可以定义一个自定义函数,这个函数内部根据当前的浏览器环境决定是直接调用eval函数,还是调用window.eval,或者使用其他方法执行代码。...

    javascript 自定义eval函数实现

    一种方法是限制执行的上下文,例如,通过将代码执行在一个沙盒环境中,防止对全局变量的直接访问。以下是一个简单的示例,创建一个安全的`eval`替代函数: ```javascript function safeEval(code) { const sandbox...

Global site tag (gtag.js) - Google Analytics