global.eval 无法访问词法范围内的变量。该行为是否符合 ECMAScript 标准?

2023-12-03

我有一个 JavaScript 文件,e.js

var global = Function('return this')();

var i = 1;

console.log(eval("100-1"));
console.log(eval("i"));

console.log(global.eval("100-1"));
console.log(global.eval("i"));

当我用V8执行它时:

$ node e.js
99
1
99

undefined:1
i
^
ReferenceError: i is not defined
    at eval (eval at <anonymous> (/private/tmp/xxxx/e.js:8:20), <anonymous>:1:1)
    at eval (native)
    at Object.<anonymous> (/private/tmp/xxxx/e.js:8:20)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

因此,global.eval适用于数学运算符,但无法访问变量i, while eval适用于两种情况。

这种行为是 V8 的限制吗?或者这是根据 ECMAScript 标准的预期行为?


是的,这是符合规范的行为。ES5 15.1.2.1.1,直接调用 Eval,表示调用的一个要求eval“直接”是指eval "有环境记录作为其基础值.” 这意味着它不能是通过属性访问完成的引用(在这种情况下,拥有的对象将是基值);它必须是一个“裸”函数。

这种区别对于步骤 1 至关重要10.4.2, 输入评估代码:

  1. If there is no calling context or if the eval code is not being evaluated by a direct call (15.1.2.1.1) to the eval function then,
    • A。使用 eval 代码作为 C 来初始化执行上下文,就像它是全局执行上下文一样,如 10.4.1.1 中所述。

因此,间接调用eval给出的是全局变量环境,而不是局部变量环境。只有直接调用才能访问本地环境。

这样做是出于实际实施的原因,因为eval可以向垃圾收集器发出需要避免清理任何变量的信号。例如,这是一个没有的情况eval:

function foo() {
    var a = 5, b = 6, c = 7;
    return function() { return a; }
}
var func = foo();
alert(func());

返回的函数foo可能会访问a after foo终止,但我们可以确定b and c之后将永远不会再被访问foo终止。b and c可以安全地进行垃圾收集,同时a仍未收集。

现在有一个案例eval:

function foo() {
    var a = 5, b = 6, c = 7;
    return function(exp) { return eval(exp); }
}
var func = foo();
alert(func("b"));

不可能一般地决定是否eval表达exp将引用给定的变量,因此垃圾收集器必须never收集任何变量,以便它们仍然可供返回的函数使用。

为了决定eval在使用中,解析器必须能够可靠地识别对eval。如果eval以间接的方式呈现,例如global["e"+"va"+"l!"[0]],规范说evaled 代码无法访问any局部变量,从而避免垃圾收集问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

global.eval 无法访问词法范围内的变量。该行为是否符合 ECMAScript 标准? 的相关文章

  • AngularJS 仅在解析时返回两个 http get 请求

    我有一个 Angular 应用程序 在控制器中我需要调用一个发出两个 http get 请求的函数 并且我需要这个函数在解析这些值时返回这些值 我无法在 routeProvider 中解析它们 因为此函数需要在同一控制器中获取值 我展示了控
  • $(window).resize() 和打印预览模式

    我有一段非常简单的代码 可以在调整大小后刷新窗口 window resize function location reload 当我尝试在 Chrome 中打开打印预览模式 Ctrl P 时 它也会刷新它 有什么想法如何避免这种行为吗 要确
  • Canvas drawImage 内联 svg 在 Firefox 上不起作用

    这是一个例子 它采用 svg 并将其转换为画布 http jsfiddle net Na6X5 944 http jsfiddle net Na6X5 944 var can document getElementById canvas1
  • Document.createElement("br") 不适用于多次调用appendChild

    HTML var x document createElement p var br1 document createElement br var br2 document createElement br var t5 document
  • Firefox 中的 jQuery 表单提交

    请帮我解决一个问题 我有这个代码 用于通过锚点提交表单
  • 将浮点值转换为灰度十六进制颜色值

    这个问题又快又简单 我有一个二维浮点数组 0 0000000 到 1 0000000 我想将这些数字转换为颜色值 000000 到 ffffff 请注意 我所说的只是灰度值 0 黑色 0 5 中灰色 1 白色 有谁知道如何用 javascr
  • jQuery 插件与小部件

    几个月前 我开始使用 jQuery 插件进行一些实验 我在互联网上找到了一些教程 然后开始整理一些东西 几天前 我需要构建自己的 插件 并回到我的旧项目 当我试图在互联网上找到更多信息时 我偶然发现了这些称为小部件的新 东西 据我了解 我应
  • ngRepeat 中的函数执行过于频繁

    我有三个tabs里面有不同的htmlng include 这些选项卡使用以下方式显示ng repeat 只有一个 HTML 模板包含函数调用 但它执行了 3 次 每个模板执行一次 ng repeat迭代 这里出了什么问题以及如何解决它 va
  • 如何从客户端设置 HTMLEditorExtender HTML

    我无法让它工作 这是我在另一个线程中找到的代码 但它对我不起作用 我得到 set content 不是函数 find set content whatever 这仍然有效吗 我还尝试设置它扩展的文本框的值 尝试设置两者的 InnerHtml
  • 使用 jQuery 触发真实事件

    看来 jQuery 的trigger 仅运行与 jQuery 绑定的事件处理程序 我有一些使用本机浏览器事件绑定的模块 使用来自的代码https stackoverflow com a 2676527 https stackoverflow
  • 如何从谷歌地图中的纬度和经度获取地址位置? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 所以我有纬度和经度就像44 4647452 and 7 3553838 我需要获得如下地址 米兰 意大利 str 肯尼迪 89 我怎样才能
  • Elasticsearch 前缀匹配消失且未添加 (QueryString)

    结转自Elasticsearch QueryStrings 部分匹配 NOT 查询 https stackoverflow com questions 40100006 elasticsearch querystrings partiall
  • 过滤文件上传仅用于文本文件

    我使用的是 Firefox 版本 14 0 1 我需要过滤上传文件窗口以仅显示 txt files 我的浏览器不仅仅支持文本文件 text plain 我可以通过指定此格式来限制图像文件 image 但我只需要过滤文本文件在文件选择器窗口中
  • 如何让 jQuery 选择带有 . (句号)在他们的身份证件中?

    给定以下类和控制器操作方法 public School public Int32 ID get set publig String Name get set public Address Address get set public cla
  • 在网站的一次导航中仅显示一次弹出窗口

    我有一个使用 Laravel 创建的网站 我希望用户第一次访问我的网站时能够看到弹出窗口 我的意思是第一次 用户访问我网站上的任何页面 这是第一次 访问网站上的一些链接页面 现在 这些页面访问不是第一次 在同一选项卡中打开 facebook
  • 在 Photoshop 中使用 javascript 修改文本项的内容

    我知道如何使用这样的代码在 Photoshop 中设置文本项的内容 var al doc activeLayer if al kind LayerKind TEXT get the textItem var ti al textItem c
  • 在单页应用程序上重用 Google Maps API 实例

    假设我有一个单页应用程序 Angular JS 应用程序 并且我在元素 id 上绘制一个 Google 地图实例googleMap var mapInstance new google maps Map document getElemen
  • Magnific Popup:来自span的源标题

    我想从锚标记内的隐藏标题字段中获取放大图像的标题 而不是从标题中获取 这是因为我的标题包含标记 HTML a href img zoom jpg img src img small jpg alt span class hide This
  • JSON.stringify 对于大型对象来说非常慢

    我在 javascript 中有一个非常大的对象 大约 10MB 当我对其进行字符串化时 需要很长时间 因此我将其发送到后端并将其解析为一个对象 实际上是带有数组的嵌套对象 这也需要很长时间 但这不是我们在这个问题中的问题 问题 我怎样才能
  • 网站可以检测您何时将 Selenium 与 chromedriver 结合使用吗?

    我一直在使用 Chromedriver 测试 Selenium 我注意到有些页面可以检测到您正在使用 Selenium 即使根本没有自动化 即使我只是通过 Selenium 使用 Chrome 手动浏览 Xephyr https en wi

随机推荐