首页 > 解决方案 > 我可以从对象创建 if 语句吗?

问题描述

我有一个 Google Chrome 扩展程序,它允许用户使用扩展程序 options.html 页面中的表单将参数保存到 chrome.storage 区域。他们输入的参数组合成一个对象,保存到 chrome.storage.local。

当他们访问一个网站时,我会从我的内容脚本中的存储中加载该对象。然后,我需要if根据用户提供的数据创建语句。

给定这样的变量(由我设置或从其他来源提取的值,而不是用户)。其他示例可能是document.referrer用户所在页面的属性,或者页面上标签的.href属性。<a>

var variable = "foo"; // this variable and its value of 'foo' here is created by me

而这个对象(由用户提供):

const ifStatement = {
  "operator": "and", // &&, logical operator selected by user
  "conditions": [
    [
      "variable", // a variable name saved to storage as a string. the user chose it from a list of provided variables
      "===",      // comparison operator saved as a string, selected by user
      "foo"       // custom string entered by user, intended by them to match against the variable they identified
    ],
    [
      "variable",
      "!==",
      "bar"
    ]
  ]
}

如何创建一个if看起来像这样的语句?

if ( variable === "foo" && variable !== "bar" ) {
  // do something
}

这是用户用来向我提供ifStatement对象中的值的 UI 的屏幕截图。也许这将有助于想象我在做什么。

在此处输入图像描述

标签: javascriptarrays

解决方案


您需要一个解释用户提供的对象的函数。对于您提供的变量,我建议将它们定义为单个对象的属性。所以而不是:

var path = "foo"

... 你将会拥有:

var vars = { path: "foo" }

该函数将采用vars用户提供的对象。它会返回falsetrue。有了这样的结果,您可以轻松编写if语句。核心问题实际上是产生布尔值。

这是如何做到的:

function evalBoolean(vars, {operator, conditions}) {
    return conditions[operator === "and" ? "every" : "some"](([name, cmp, value]) => ({
            "===": (a, b) => a === b,
            "!==": (a, b) => a !== b,
            "<"  : (a, b) => a < b,
            ">"  : (a, b) => a < b,
            "<=" : (a, b) => a <= b,
            ">=" : (a, b) => a >= b,
        })[cmp](vars[name], value)
    );
}

// Demo
var vars = { path: "foo" };

const expression = {
  "operator": "and",
  "conditions": [
    [
      "path",
      "===",
      "foo"
    ],
    [
      "path",
      "!==",
      "bar"
    ]
  ]
}

console.log(evalBoolean(vars, expression));


推荐阅读