lam*_*345 -3 javascript with-statement strict-mode ecmascript-6
此代码运行最佳并且易于理解:
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!
Run Code Online (Sandbox Code Playgroud)
然而,“聪明”的大脑决定删除该with声明,而不进行适当的替换。
问题:如何让它在自动处于严格模式的 ES6 中再次工作?
不要使用eval,而是创建一个new Function。它不会继承词法严格模式 - 更好的是,它不会继承所有函数范围和模块范围的变量:
"use strict";
function evalInScope(js, contextAsScope) {
return new Function(`with (this) { return (${js}); }`).call(contextAsScope);
}
console.log(evalInScope("a + b", { a: 1, b: 2 })); // 3Run Code Online (Sandbox Code Playgroud)
此外,您不会得到eval使用的奇怪的“(最后)语句结果”返回值,但可以将js代码限制为表达式或return在代码本身中包含语句。
或者,如果您实际上并不需要使用with复杂的语句,而只是想让一组动态常量变量可供evaled 代码使用,则只需动态生成这些常量的代码即可。这甚至允许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 })); // 3Run Code Online (Sandbox Code Playgroud)
或者如果代码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 })); // 3Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |