【问题标题】:Pattern matching in JavaScript?JavaScript 中的模式匹配?
【发布时间】:2020-05-26 09:49:09
【问题描述】:

我需要在 JavaScript 中创建一个变量并根据条件为其赋值。这可行,但感觉有点冗长:

  const color = (() => {
    switch (type) {
      case "primary":
        return CONSTANTS.colors.primary;
      case "secondary":
        return CONSTANTS.colors.secondary;
      case "tertiary":
        return CONSTANTS.colors.tertiary;
      case "positive":
        return CONSTANTS.colors.positive;
      case "negative":
        return CONSTANTS.colors.negative;
      case "disabled":
        return CONSTANTS.colors.disabled;
      default:
        throw new Error("A backgroundColor condition was missed");
    }
  })();

我正在尝试做的事情称为“模式匹配”吗?我读过 JavaScript 没有这个功能,但我不完全确定它是什么。

上面的代码有更简洁的写法吗?我可以有很多 if 声明,但这感觉更混乱,需要变量是 let 而不是 const

let color:
if (type === "primary") {
    color = CONSTANTS.colors.primary;
} else if(type === "secondary") {
    color = CONSTANTS.colors.secondary;
} else if(type === "tertiary") {
    color = CONSTANTS.colors.tertiary;
} else if(type === "secondary") {
    color = CONSTANTS.colors.secondary;
} else if(type === "positive") {
    color = CONSTANTS.colors.positive;
} else if(type === "negative") {
    color = CONSTANTS.colors.negative;
} else if(type === "disabled") {
    color = CONSTANTS.colors.disabled;
}

【问题讨论】:

  • JS没有模式匹配是什么意思?您似乎在这里混淆了一些东西。

标签: javascript pattern-matching


【解决方案1】:

解决问题的最简单方法是检查type 是否在对象CONSTANTS.colors 中定义。如果要通过变量访问属性,则需要使用括号注解。括号内的所有内容都被评估为一个表达式(因此type 是一个变量,'type' 是字符串值)。因此,object.type 返回的值与object['type'] 相同。

let color = null;
if (typeof CONSTANTS.colors[type] !== 'undefined') {
   color = CONSTANTS.colors[type];
} else {
   throw new Error('A backgroundColor condition was missed');
}
console.log(color);

也可以先用Object.keys()includes()检查对象中是否定义了key:

let color = null;
if (Object.keys(CONSTANTS.colors).includes(type)) {
    color = CONSTANTS.colors[type];
} else {
   throw new Error('A backgroundColor condition was missed');
}
console.log(color);

如果你想支持IE11,你cannot use .includes()。使用.indexOf(type) !== -1 而不是.includes(type)

【讨论】:

    【解决方案2】:

    模式匹配通常是指匹配传递给函数的参数:测试它们是否匹配特定的“模式”。例如,模式匹配可能允许您编写一个以“两种不同方式”接受整数参数的函数,一种是传入的参数是0,另一种是传入的参数不是0(“否则“ 案子)。 Switch 语句与这种类型的分支逻辑有些相似,但与 Haskell 之类的纯函数式语言不同,在这里对您的目标没有太大帮助。

    换成这样的怎么样?

    const myColor = CONSTANTS["colors"][type];
    if(typeof myColor !== 'undefined') {
        color = myColor;
    } else {
       throw new Error("A backgroundColor condition was missed");
    }
    

    【讨论】:

      【解决方案3】:

      您正在寻找property accessor:

      color = CONSTANTS.colors[type];
      

      【讨论】:

        【解决方案4】:

        您的代码的简单替换是

        const color = (() => {
            const color = CONSTANTS.colors[type];
            if (!color) {
                throw new Error("A backgroundColor condition was missed");
            }
            return color;
          }
          })();
        

        不,那不是模式匹配。

        【讨论】:

          【解决方案5】:

          我认为引入一个可以保存颜色值的 Enum 是明智的。

          var ColorType = {
                  Primary: "primary",
                  Secondary: "secondary",
                  Tertiary: "tertiary,
                  ...
          };
          

          然后您可以在 switch case 中使用此枚举,您将避免拼写错误和直接引用字符串。 我认为这将使代码不那么冗长,并且不易出错。

          【讨论】:

            【解决方案6】:

            您可以通过将属性名称用作方括号中的字符串来访问对象的属性。

            (此示例不包括您在 switch 语句中使用的错误捕获,但您可以添加它。)

            const CONSTANTS = {
              colors: {
                primary: "blue",
                secondary: "yellow"
              }
            } 
            
            function getColor(myPropName){
              // Pass dynamic property names like this
              return CONSTANTS.colors[myPropName];
            }
            
            console.log(getColor("secondary"));

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-05-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多