深入认识javascript中的eval函数(转)

简介: 文章写得很好。 转自:http://www.enjoyphp.com/2009/05/25/javascript/js-eval/ 先来说eval的用法,内容比较简单,熟悉的可以跳过。eval函数接收一个参数s,如果s不是字符串,则直接返回s。

文章写得很好。

转自:http://www.enjoyphp.com/2009/05/25/javascript/js-eval/

先来说eval的用法,内容比较简单,熟悉的可以跳过。
eval函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句。如果s语句执行结果是一个值,则返回此值,否则返回undefined。
需要特别注意的是对象声明语法“{}”并不能返回一个值,需要用括号括起来才会返回值,简单示例如下:

1
2
3
4
5
    var code1='"a" + 2';    //表达式
    var code2='{a:2}';      //语句
    alert(eval(code1));     //->'a2'
    alert(eval(code2));     //->undefined
    alert(eval('(' + code2 + ')'));    //->[object Object]

可以看到,对于对象声明语句来说,仅仅是执行,并不能返回值。为了返回常用的“{}”这样的对象声明语句,必须用括号括住,以将其转换为表达式,才能返回其值。这也是使用JSON来进行Ajax开发的基本原理之一。在例子中可以清楚的看到,第二个alert语句输出的是undefined,而第三个加了括号后输出的是语句表示的对象。
现在来说本文的重点,如何在函数内执行全局代码。为了说明这个问题,先看一个例子:

1
2
3
4
5
6
    var s='global';    //定义一个全局变量
    function demo1(){
        eval('var s="local"');
    }
    demo1();
    alert(s);    //->global

很好理解,上面的demo1函数等价于:function demo1(){var s=’local’;},其中定义了一个局部变量s。
所以最后的输出是global并不是什么奇怪的事情,毕竟大家都能很清楚的区分局部变量和全局变量。
仔细体会一下,可以发现eval函数的特点,它总是在调用它的上下文变量空间(也称为:包,closure)内执行,无论是变量定义还是函数定义都是如此,所以如下的代码会产生函数未定义的错误:

1
2
3
4
5
6
    var s='function test(){return 1;}';     //一个函数定义语句
    function demo2(){
        eval(s);
    }
    demo2();
    alert(test());    //->error:test is not defined

这是因为test函数在局部空间定义,demo2函数内可以访问到,外面就访问不到了。

而在实际的Ajax开发中,有时我们需要从服务器动态获取代码来执行,以减轻一次载入代码过多的问题,或者是一些代码是通过Javascript自身生成的,希望用eval函数来使其执行。
但这样的动态获取代码的工作一般在函数内完成,比如:

1
2
3
4
    function loadCode(){
        var code=getCode();
        eval(code);
    }

可见eval不可能在全局空间内执行,这就给开发带来了不少问题,也看到过很多人为此郁闷。
不过现在偶终于找到了解决办法,嘿嘿,可以同时兼容IE和Firefox,方法如下:

1
2
3
4
5
6
7
8
9
10
    var X2={}    //my namespace:)
    X2.Eval=function(code){
     if(!!(window.attachEvent && !window.opera)){
      //ie
      execScript(code); 
     }else{
      //not ie
      window.eval(code);
     }
    }

现在如果要想在函数内定义全局代码,就可以通过调用X2.Eval(code)方法,一个例子如下:

1
2
3
4
5
6
    var s='global';
    function demo3(){
     X2.Eval('var s="local"');
    }
    demo3();
    alert(s); //->'local'

可见,在demo3函数内重新定义了全局变量s=”local”。
需要注意的是X2.Eval并不返回值,如果要进行表达式的求值,还是用系统的eval函数。X2.Eval设计为仅做全局代码定义用。
其实看到这里,或许有人感觉问题也太容易解决了点,呵呵,但发现这个办法倒是需要些运气和技巧的:
(1)对于IE浏览器,默认已经提供了这样的函数:execScript,用于在全局空间执行代码,只是知道的人还不多。
(2)对于Firefox浏览器,直接调用eval函数,则在调用者的空间执行;如果调用 window.eval则在全局空间执行。这个知道的人估计就更少了。毕竟alert(eval==window.eval)返回true!
Firefox的eval函数的特点的确是很令人奇怪的,但从javascript规范中倒也能找到其来源:
If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its
name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to,
an EvalError exception may be thrown.
意思大概就是说eval函数的执行是和调用者相关的,但并没有说其执行上下文的问题。所以IE和Firefox孰是孰非也就很难说了,大家知道解决办法就好。

 

博客园大道至简

http://www.cnblogs.com/jams742003/

转载请注明:博客园

目录
相关文章
|
12月前
|
机器学习/深度学习 算法 大数据
蓄水池抽样算法详解及Python实现
蓄水池抽样是一种适用于从未知大小或大数据集中高效随机抽样的算法,确保每个元素被选中的概率相同。本文介绍其基本概念、工作原理,并提供Python代码示例,演示如何实现该算法。
278 1
|
11月前
|
自然语言处理 前端开发 网络协议
用 Qwen2.5-Coder 开发一个网页应用,完全0基础,已部署上线,代码开源!
利用Qwen2.5-Coder成功开发了一个简洁实用的网页应用,该应用能够在浏览器Tab标题中显示北京时间,并在页面中集成了实时时间显示和番茄时钟功能。通过Qwen2.5-Coder的强大代码生成能力,从零基础开始,仅需简单提示便完成了HTML、CSS和JavaScript的编写。经过几次优化调整,最终实现了美观且功能完善的网页应用,并顺利部署至Vercel平台,满足了作者在全屏模式下查看时间的需求。
用 Qwen2.5-Coder 开发一个网页应用,完全0基础,已部署上线,代码开源!
|
10月前
|
人工智能
精度与通用性不可兼得,北大华为理论证明低精度下scaling law难以实现
北京大学和华为的研究团队在论文《数值精度如何影响大型语言模型的数学推理能力》中指出,数值精度是影响Transformer模型在数学任务中表现的关键因素。研究发现,低数值精度下,模型难以处理算术任务,如迭代加法和整数乘法;而在标准数值精度下,模型表现更佳且所需规模较小。实验结果表明,提高数值精度可显著提升LLM的数学推理能力,为优化模型性能提供了新思路。
242 88
|
API 开发者
在线CAD实现图纸比较功能
MXCAD提供了一项实用的图纸比对功能,帮助设计师高效识别不同版本CAD图纸间的改动。用户只需几个简单步骤即可启动比对过程:打开MXCAD在线示例,上传目标图纸,选择“图纸比对”并加载待比对文件。系统会清晰标出所有差异,甚至支持实体定位以便更直观地查看变化细节。此外,MXCAD还开放了相关API,允许开发者根据具体需求进行定制化二次开发,如利用`McObject.loadDwgBackground()`方法加载背景图纸并通过`MxCompare`类获取差异数据等。关注“梦想云图网页CAD”公众号了解更多资讯。
596 99
在线CAD实现图纸比较功能
|
11月前
|
存储 人工智能 监控
【AI系统】推理系统架构
本文深入探讨了AI推理系统架构,特别是以NVIDIA Triton Inference Server为核心,涵盖推理、部署、服务化三大环节。Triton通过高性能、可扩展、多框架支持等特点,提供了一站式的模型服务解决方案。文章还介绍了模型预编排、推理引擎、返回与监控等功能,以及自定义Backend开发和模型生命周期管理的最佳实践,如金丝雀发布和回滚策略,旨在帮助构建高效、可靠的AI应用。
918 15
|
存储 SQL 分布式计算
湖仓一体架构深度解析:构建企业级数据管理与分析的新基石
【10月更文挑战第7天】湖仓一体架构深度解析:构建企业级数据管理与分析的新基石
834 1
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用问题之如何进行MySQL到MySQL的动态同步
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
Web App开发 存储 算法
Web身份验证(WebAuthn)(下)
Web身份验证(WebAuthn)(下)
|
机器学习/深度学习 Python
Python 金融量化 道路突破策略(唐奇安道路突破策略&布林带通道及其市场风险)
Python 金融量化 道路突破策略(唐奇安道路突破策略&布林带通道及其市场风险)
1936 0
Python 金融量化 道路突破策略(唐奇安道路突破策略&布林带通道及其市场风险)
|
安全 JavaScript 小程序
云支付官方FAQ
云支付官方小二实时更新的浓缩FAQ,帮助广大服务商快速定位问题。