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

如何在with语句内部函数中使用注入作用域并获取$self变量

问题分析与解决方案

原代码问题

原代码中,$sys.comp的getter函数无法访问with语句中注入的$self,核心原因是函数的作用域由定义时的词法环境决定,而非调用时的环境。getter定义在全局作用域,它的作用域链里不包含with注入的变量环境,因此查找$self时会报错。

实现方案(不移动Object.defineProperty)

要让getter访问到with中的$self,可以利用eval的动态作用域特性——eval会在当前执行上下文(即with的作用域)中查找变量:

const $sys = {};
Object.defineProperty($sys, 'comp', {
  get: function() {
    // 使用eval在当前执行上下文查找$self
    console.log('====', eval('$self'));
  }
});

with({ $self: 1 }) {
  console.log($sys.comp); // 输出 ==== 1
}

关于with语句内部函数使用注入作用域的说明

  1. 函数在with内部定义:
    如果函数直接在with语句块内定义,它的词法作用域会包含with注入的变量环境,自然能访问到注入的变量:

    with({ $self: 1 }) {
      function logSelf() {
        console.log($self); // 直接访问到$self
      }
      logSelf(); // 输出 1
    }
    
  2. 函数在with外部定义:
    外部定义的函数无法直接访问with的注入变量,因为词法作用域不包含该环境,此时有两种可行方式:

    • 使用eval动态查找:如上面的解决方案,利用eval在调用时的上下文查找变量。
    • 显式传递变量:调用函数时将with中的变量作为参数传入:
      const $sys = {};
      $sys.getSelf = function(self) {
        console.log('====', self);
      };
      
      with({ $self: 1 }) {
        $sys.getSelf($self); // 输出 ==== 1
      }
      

注意:with语句在严格模式下会被禁用,且过度使用可能导致代码可读性下降,实际开发中建议尽量避免使用,改用对象解构或直接属性访问替代。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:05:31