我们有产品(普通桌面应用程序),希望从Adobe产品(从文档,在这些产品中打开)中提取一些数据.由于Apple事件太慢,我们实现了一个定制互操作,它通过套接字将生成的JSX(Adobe的ActionScript3基于不太久的JAVASCRIPT1.5)发送到Adobe产品进程.这比使用事件快2000多倍,但迫使我们做一些涉及eval的技巧,当前的目标是将非隔离的eval无意中 destruct JSX引擎状态的风险降至最低.

此代码在受信任的环境(不是浏览器)中运行,并且代码本身也是受信任的,因此关于eval的任何安全注意事项都不适用.这个问题的主要目的是防止eval人造成全球范围的污染.

当使用eval时,则最后一个表达式的结果被认为是整个eval的返回值,例如,后面代码的eval-ing的结果将是y+2=12表达式的值.

var res = eval("
    var x = 5;
    var y = x*2;
    y+2;
"); //res = 12 

同时,如果我们将这样的代码包装到Function构造函数中,那么结果将是undefined

var res = (new Function("
    var x = 5;
    var y = x*2;
    y+2;
")).call(); //res=undefined

要修复最后一段代码,我们需要向最后一个表达式添加显式返回:

var res = (new Function("
    var x = 5;
    var y = x*2;
    return y+2;    // <------- changes here
")).call(); //res=12

因此,evalFunction具有不同的返回语义.

我不能把eval替换成Function().我还将被迫更改调用方,在代码中添加return ,传递给Function().

有没有一种方法可以避免添加显式返回,这样就可以以透明的方式用Function()替换eval(假设我们对访问本地作用域不感兴趣)?

或者,也许存在另一种技术,它可以提供等同于eval的技术,从而将全球范围污染的风险降至最低,并提供与最初的eval相同的返回语义?

推荐答案

请注意,为了技术上的正确性,您显示的初始evalnot只会导致12,它会导致everything you wrote =)

eval是一个宏,它暂停JS执行,替换您给它的代码,执行它,然后恢复常规执行.因此,在本例中,结果是两个新变量xy,它们位于运行eval的相同作用域中,而"12"只是因为赋值是返回操作这一事实.

如果你不想在你的作用域中引入任何新的东西,那么记住eval是一个宏:在你需要的代码中把它变成sub:

eval("(function() { var x=5; y=7; return x + y; })()");

(或者使用Alexander的解决方案,即创建一个以eval为函数体的"实"函数)

当然,这也可以很好地接受争论:

var someVar = 5;
var someOtherVar = 7;
var result = 0;
eval(
  "result = (function(a,b) { return a+b; })(" + someVar + "," + someOtherVar + ")"
);

它现在将运行一个IIFE,它执行它需要做的任何事情,返回12,然后得到垃圾收集.

但当然,这是重要的部分:如果这是你需要的,那么你不需要判断任何东西.您只需编写函数并使用已有的值调用它.您几乎从不需要eval,即使在Adobe脚本中也是如此.

Javascript相关问答推荐

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

使用redux-toolet DelivercThunks刷新访问令牌

提交表格后保留Web表格中的收件箱值?

在Angular中将样式应用于innerHTML

JQuery. show()工作,但. hide()不工作

为什么ngModel不能在最后一个版本的Angular 17上工作?'

D3 Scale在v6中工作,但在v7中不工作

引用在HTMLAttributes<;HTMLDivElement>;中不可用

在Three JS中看不到补间不透明度更改效果

在Java中寻找三次Bezier曲线上的点及其Angular

如何将数组用作复合函数参数?

Webpack在导入前混淆文件名

按下单键和多值

在SHINY R中的嵌套模块中,不能使用Java代码

当代码另有说明时,随机放置的圆圈有时会从画布上消失

删除加载页面时不存在的元素(JavaScript)

如何使用抽屉屏幕及其子屏幕/组件的上下文?

在SuperBase JS客户端中寻址JSON数据

我的NavLink活动类在REACT-ROUTER-V6中出现问题

如何格式化API的响应