You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ES6严格模式下替代with语句实现作用域内代码求值

解决ES6严格模式下替代with实现作用域内代码执行的问题

原代码依赖with语句将上下文对象作为作用域,但严格模式下with被禁用,导致代码失效。以下是两种符合ES6严格模式规范的替代方案:

方案1:利用new Function动态注入上下文属性作为参数

这种方式通过将上下文对象的属性作为函数参数传入,让执行代码可以直接访问变量,完全兼容严格模式:

function evalInScope(js, contextAsScope) {
  const [keys, values] = [Object.keys(contextAsScope), Object.values(contextAsScope)];
  return new Function(...keys, js)(...values);
}

// 测试用例
console.log(evalInScope("a + b", {a: 1, b: 2})); // 3
console.log(evalInScope("Math.min(x, y)", {x: 3, y: 1})); // 1

优势:实现简单,性能优异,无额外运行时开销;
局限:需要提前枚举上下文属性,若上下文属性动态变化,需重新调用函数。

方案2:使用Proxy拦截变量查找(支持动态属性)

如果需要支持动态添加的上下文属性,或不想提前枚举属性,可以用Proxy拦截变量读取操作,从上下文对象中获取对应值:

function evalInScope(js, contextAsScope) {
  const proxy = new Proxy(contextAsScope, {
    get(target, prop) {
      if (prop in target) {
        return target[prop];
      }
      throw new ReferenceError(`${String(prop)} is not defined`);
    }
  });

  return new Function(`return (${js})`).call(proxy);
}

// 测试用例
console.log(evalInScope("a + b", {a: 1, b: 2})); // 3
// 支持动态添加属性
const ctx = {foo: 5};
ctx.bar = 10;
console.log(evalInScope("foo * bar", ctx)); // 50

优势:支持动态属性,无需提前枚举;
局限:Proxy存在轻微性能开销,适合上下文属性频繁变化的场景。

重要提示

  • 动态执行代码(eval/new Function)存在安全风险,务必仅执行可信代码,防止注入攻击;
  • 两种方案均完全符合ES6严格模式规范,可直接在默认启用严格模式的环境中运行;
  • 若上下文包含嵌套对象,两种方案都支持通过obj.prop的语法访问嵌套属性(如evalInScope("user.age", {user: {age: 25}}))。

内容的提问来源于stack exchange,提问作者kungfooman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:37:43