如何使用 Ramda 执行数组中的表达式字符串

How to execute strings of expression in an array with Ramda

我有一个数组,其中列出了表达式字符串。

const newPIXI = ["container1 = new PIXI.Container();","container2 = new PIXI.Container();","container3 = new PIXI.Container();"]

我用 (Function(...newPIXI))()

成功地 运行

我如何使用 Ramda 执行此操作? 我试过 R.forEach ,但没用。

这些是字符串,不是函数。要 运行 他们,您需要使用 eval() (or Function 评估他们,然后 运行 他们)。每个字符串都是一个表达式,而不是一个实际的函数。 运行 表达式将创建全局变量(container1container2container3)。

您可能听说过 eval() 邪恶的 。使用 eval() 存在安全风险,并且会损害性能,而 Function 只是稍微少一点 (read more here):

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, a third-party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

Function 的优点是它 运行 在全局范围内,并且不能访问它被调用的范围内的变量。但是,Function 仍然允许 运行ning 任意代码。

评估示例:

const PIXI = {
  Container: function () {
    this.example = 'Container';
  }
};

const newPIXI = ["container1 = new PIXI.Container();","container2 = new PIXI.Container();","container3 = new PIXI.Container();"]

newPIXI.forEach(x => eval(x))

console.log({ container1, container2, container3 });

函数示例:

const PIXI = {
  Container: function () {
    this.example = 'Container';
  }
};

const newPIXI = ["container1 = new PIXI.Container();","container2 = new PIXI.Container();","container3 = new PIXI.Container();"]

newPIXI.forEach(x => Function(x)())

console.log({ container1, container2, container3 });

最好传递数据告诉浏览器你想做什么(一个命令),而不是如何做。然后在代码中您可以决定如何解释命令。例如:

const PIXI = {
  Container: function () {
    this.example = 'Container';
  }
};

const newPIXI = [{ type: 'PIXIContainer', name: 'container1' }, { type: 'PIXIContainer', name: 'container2' }, { type: 'PIXIContainer', name: 'container3' }]

const result = {};

newPIXI.forEach(({ type, name }) => {
  switch(type) {
    case 'PIXIContainer':
      result[name] = new PIXI.Container();
      break;
    default:
      throw new Error(`Type ${type} not found`);
  }
})

console.log(result);