gpt4 book ai didi

javascript - 在有限上下文中运行 JS 代码

转载 作者:数据小太阳 更新时间:2023-10-29 06:14:43 24 4
gpt4 key购买 nike

我正在尝试在“隔离”上下文中运行可信 JS 代码。基本上想出了这个方法:

function limitedEval(src, context) {
return (function() {
with(this) {
return eval(src)
}
}).call(context)
}

这很好用,但是当脚本使用 var 关键字时,它存储在 execution context 中,而不是 with 语句中提供的上下文(我理解是设计使然)。因此,例如,以下代码不起作用:

var ctx = {};
limitedEval('var foo = "hello"', ctx);
limitedEval('alert(foo)', ctx); // error: foo is undefined

我希望能够多次调用 limitedEval() 并重用上下文。这可能吗?

最佳答案

这似乎是一个非常有趣的问题。您的代码的问题是每次执行 limitedEval 时都会生成新函数。这意味着您使用 var 关键字创建的任何变量都只会存在于该函数的上下文中。您真正需要的是每个上下文有 1 个函数并重用该函数的上下文。最明显的方法是使用 generators .生成器本质上是可以暂停然后重新启动的函数。

// IIFE to store gen_name
var limitedEval = function() {
// Symbol for generator property so we don't pollute `ctx` namespace
var gen_name = Symbol();

return function limitedEval(src, context) {
if(!(gen_name in context)) {
// Generator that will run eval and pause til getting the next source code
var generator = function * () {
with(this) {
while(true) {
yield eval( yield );
}
}
};

context[gen_name] = generator.call(context);

// Initially, we need to execute code until reaching the first `yield`
context[gen_name].next();
}

// First, send the source to the `eval`
context[gen_name].next( src );

// Second, get the `eval` result
return context[gen_name].next().value;
};
}();

现在你可以调用

var ctx = {};
limitedEval('var foo = "hello"', ctx);
limitedEval('alert(foo);', ctx);

每个 limitedEval 调用现在将重用它在提供的 ctx 对象上找到的任何生成器函数。如果该函数不存在,它将创建它并将其放在 ctx 对象上。因为现在每个 ctx 只有一个函数,所以在使用 var 关键字创建变量时它将重用函数的上下文。注意:您将无法通过 ctx 对象查找这些变量,因为它们只存在于函数的上下文中。

我不完全确定你是否可以在不使用生成器的情况下获得相同的结果。

编辑:其他人提出了很好的建议,所以我用 Symbol 替换了随机生成的属性,并用 with(this) 而不是 with (上下文)

关于javascript - 在有限上下文中运行 JS 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43989742/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com