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

Angular同类别函数间变量访问问题及代码重构咨询

解决方法:让evaluateResult访问execute中的namesSplit变量

嘿,作为初学者碰到这种作用域问题太正常了,我给你两种清晰的重构方案,顺便还会修正代码里的小bug,帮你彻底搞定:

方案1:直接传递namesSplit作为参数(推荐,无状态残留)

这是最直接且安全的方式——既然execute主动调用evaluateResult,那直接把namesSplit当作参数传过去就行,完全不需要修改类的状态:

首先修改execute里的调用逻辑:

if (namesSplit.length > 1) {
  this.evaluateResult(contextEntry.value, namesSplit);
}

然后更新evaluateResult的定义和内部逻辑,同时修正原代码里的几个明显问题:

evaluateResult(val: any, namesSplit: string[]) {
  if (this.getType(val) === ExpressionVariableType.OBJECT) {
    return Object.values(val);
  } else if (this.getType(val) === ExpressionVariableType.ARRAY_OF_OBJECTS) {
    for (let obs of val) {
      // 修正:原逻辑里直接拿字符串和数组比较是错误的,改成检查对象是否包含目标key
      const targetKey = namesSplit[0]; // 按你原逻辑的意图,取分割后的第一个key
      if (obs.hasOwnProperty(targetKey)) {
        let result = Object.values(obs[targetKey]);
        console.log(result);
        break;
      }
    }
  } else if (this.getType(val) === ExpressionVariableType.ARRAY_OF_PRIMITIVES) {
    throw new StdException('Array of Primitives not allowed!');
  } else if (this.getType(val) === ExpressionVariableType.PRIMITIVE) {
    throw new StdException('Primitive values not allowed!'); // 修正拼写错误:Primtive → Primitive
  }
}

方案2:将namesSplit设为类的实例属性(适合多方法复用场景)

如果你的类需要在多个方法里复用namesSplit,可以把它定义成类的实例变量,但要注意状态残留问题(如果同一个实例多次调用execute,namesSplit会被覆盖):

首先在类里添加实例属性:

export class ExecutableVariableNode implements IExecutableNode {
  private namesSplit?: string[]; // 定义实例变量,用?标记为可选

  // ... 其他方法保持不变
}

然后在execute里给这个变量赋值:

execute(treeNode: ExpressionTreeNode, exprData: ExpressionData): any {
  this.namesSplit = treeNode.name.split('.'); // 赋值给实例变量
  let key = this.namesSplit[0];
  let contextEntry = exprData.contextEntry.find(_x => _x.name === key);
  if (this.namesSplit.length > 1) {
    this.evaluateResult(contextEntry.value);
  }
}

最后在evaluateResult里直接使用this.namesSplit,记得加安全校验:

evaluateResult(val: any) {
  if (!this.namesSplit) {
    throw new Error('namesSplit has not been initialized!'); // 防止未赋值就调用
  }
  
  if (this.getType(val) === ExpressionVariableType.OBJECT) {
    return Object.values(val);
  } else if (this.getType(val) === ExpressionVariableType.ARRAY_OF_OBJECTS) {
    for (let obs of val) {
      const targetKey = this.namesSplit[0];
      if (obs.hasOwnProperty(targetKey)) {
        let result = Object.values(obs[targetKey]);
        console.log(result);
        break;
      }
    }
  } else if (this.getType(val) === ExpressionVariableType.ARRAY_OF_PRIMITIVES) {
    throw new StdException('Array of Primitives not allowed!');
  } else if (this.getType(val) === ExpressionVariableType.PRIMITIVE) {
    throw new StdException('Primitive values not allowed!');
  }
}

额外提示

原代码里还有几个小细节需要调整:

  • LapsExpressionVariableType看起来是笔误,建议和前面的ExpressionVariableType保持一致
  • 原逻辑里namesSplit[n] == Object.keys(obs)完全错误,因为Object.keys(obs)返回的是数组,不能直接和字符串比较,我在上面的代码里已经修正了这个逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:33:11