提问人:kungfooman 提问时间:8/28/2023 更新时间:8/28/2023 访问量:89
如何在严格模式下替换“with”语句
How to replace `with` statement in strict mode
问:
此代码以最佳方式工作且易于理解:
function evalInScope(js, contextAsScope) {
//# Return the results of the in-line anonymous function we .call with the passed context
return function() {
with(this) {
return eval(js);
};
}.call(contextAsScope);
}
evalInScope("a + b", {a: 1, b: 2}); // 3 obviously, but fails in strict mode!
然而,“聪明”的大脑决定在没有适当替换的情况下删除该声明。with
问:如何让它在自动处于严格模式的 ES6 中再次工作?
答:
0赞
Cerbrus
8/28/2023
#1
问题是你正在尝试做一些严格模式特别阻止的事情。
所以,基本上,你想做的事情是不可能的。
你要么不得不选择不使用使用严格模式,要么你将不得不解决使用(我个人建议永远不要使用......eval
eval
5赞
Bergi
8/28/2023
#2
不要使用 ,而是创建一个新的函数
。它不会继承词法严格模式 - 更好的是,它不会继承所有函数范围和模块范围的变量:eval
"use strict";
function evalInScope(js, contextAsScope) {
return new Function(`with (this) { return (${js}); }`).call(contextAsScope);
}
console.log(evalInScope("a + b", { a: 1, b: 2 })); // 3
此外,您不会获得奇怪的“(最后一个)语句结果”返回值,但可以将代码限制为表达式,也可以在代码本身中包含语句。eval
js
return
或者,如果您实际上不需要使用具有所有复杂性的语句,而只是想使一组动态的常量变量可供 ed 代码使用,则只需动态地为这些常量生成代码即可。这允许代码在严格模式下甚至:with
eval
eval
"use strict";
function evalInScope(js, contextAsScope) {
return new Function(
`"use strict";
const {${Object.keys(contextAsScope).join(', ')}} = this;
return (${js});`
).call(contextAsScope);
}
console.log(evalInScope("a + b", { a: 1, b: 2 })); // 3
或者,如果代码不使用关键字本身,也许也this
"use strict";
function evalInScope(js, contextAsScope) {
return new Function(
'{' + Object.keys(contextAsScope).join(', ') + '}',
`return (${js});`
)(contextAsScope);
}
console.log(evalInScope("a + b", { a: 1, b: 2 })); // 3
评论
0赞
kungfooman
8/28/2023
非常感谢,您的答案始终是有根据的!刚刚测试过,它运行良好。为了更短,是否可以删除第一个参数(这是和之前的参数),或者您对此有不好的体验?就像也不需要''
new
Function
Error
new Error
1赞
Bergi
8/28/2023
这不是必需的。我没有费心去阅读我链接的 mdn 页面:-)我记得这样的事情,但我总是使用双参数版本,并为参数声明传递一个逗号分隔的字符串。
0赞
Cerbrus
8/28/2023
所以,答案是基本上打破严格模式,用任何方式......我知道这是如何工作的,但那是......时髦。with
0赞
Bergi
8/28/2023
@Cerbrus 是的,如果你真的需要使用(例如,使用代理来拦截所有非局部变量访问),那么你就无法绕过它。但实际上有更好的方法可以在严格模式下工作,请参阅更新with
0赞
Cerbrus
8/28/2023
这些确实好多了!
评论
with
eval
eval
vm
模块中有一些有趣的 API,它们可能允许你做这样的事情。3. 您可以使用构造函数代替 ,这允许您传入动态命名的参数。Function
eval
vm
Function
Function