Сопоставление с образцом в JavaScript? - PullRequest
0 голосов
/ 26 мая 2020

Мне нужно создать переменную в 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;
}

Ответы [ 6 ]

1 голос
/ 26 мая 2020

Самое простое решение вашей проблемы - проверить, определено ли type в объекте CONSTANTS.colors. Если вы хотите получить доступ к свойству по переменной, вам необходимо использовать аннотацию в скобках. Все, что находится в скобках, оценивается как выражение (поэтому type - это переменная, 'type' - значение String). Следовательно, 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():

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, вы не можете использовать .includes(). Используйте .indexOf(type) !== -1 вместо .includes(type).

0 голосов
/ 26 мая 2020

Вы можете получить доступ к свойству объекта, используя имя свойства в виде строки в квадратных скобках.

(Этот пример не включает перехват ошибок, который вы использовали в своем операторе 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"));
0 голосов
/ 26 мая 2020

Я думаю, что было бы разумно ввести Enum, который будет содержать значения цвета.

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

Тогда вы можете использовать это перечисление в случае переключателя, и вы избежите опечаток и ссылок непосредственно на строку. Думаю, это сделает код менее многословным и менее подверженным ошибкам.

0 голосов
/ 26 мая 2020

Простая замена вашего кода:

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

И нет, это не сопоставление с образцом.

0 голосов
/ 26 мая 2020

Сопоставление с образцом обычно относится к сопоставлению аргументов, передаваемых функции: проверка, чтобы увидеть, соответствуют ли они заданному c «образцу». Например, сопоставление с шаблоном может позволить вам написать функцию, которая принимает целочисленный аргумент «двумя разными способами», в одном из которых передается аргумент 0, а во втором - не 0 (в противном случае " кейс). Операторы switch несколько похожи на этот тип логики ветвления c, но отличаются от чисто функционального языка, такого как Haskell, и не совсем помогают в достижении вашей цели.

Как насчет чего-нибудь как это вместо этого?

const myColor = CONSTANTS["colors"][type];
if(typeof myColor !== 'undefined') {
    color = myColor;
} else {
   throw new Error("A backgroundColor condition was missed");
}
0 голосов
/ 26 мая 2020

Вы ищете аксессуар :

color = CONSTANTS.colors[type];
...