Какова цель операторов логического переключателя в JavaScript? - PullRequest
9 голосов
/ 16 декабря 2010

Я только что столкнулся с оператором логического переключателя в чужом коде JavaScript. Это выглядело примерно так:

switch (a || b) {
  case true:
    // do some stuff
  break;
  default:
    // do other stuff
  break;
}

Я давно не программировал, но я никогда раньше не видел ничего подобного. Это кажется глупым, но я хотел бы дать программисту преимущество сомнения. Есть ли функциональная разница между приведенным выше кодом и следующим:

if (a || b) {
  // do some stuff
}
else {
  // do other stuff
}

А если есть, то что это?

Ответы [ 5 ]

8 голосов
/ 16 декабря 2010

Да, есть разница. Принимая во внимание ваш пример,

var a = 0,
    b = 1;

Теперь давайте посмотрим на оператор switch:

switch (a || b) {

Когда выполняется этот оператор switch, вычисляется выражение a || b. || - оператор короткого замыкания, он вернёт значение левого операнда, если оно «правдиво», иначе вернет значение правого операнда. В этом случае a = 0, поэтому будет возвращено b (1). Теперь посмотрим на утверждение case:

case true:

При оценке операторов case приведение типов не выполняется ни для одного из значений, и предполагается строгое равенство. В нашем примере это то же самое, что написать 1 === true, поэтому код, следующий за оператором case, никогда не запускается. Итак, давайте посмотрим на оператор if:

if (a || b) {

Для оператора if условное выражение a || b оценивается , а затем результат преобразуется в логическое значение . Внутренне это выглядит как ToBoolean(a || b). Поскольку a || b оценивается как 1, а приведение 1 к логическому значению равно true, условие проходит, и блок выполняется.

Лучшим эквивалентом будет:

if ((a || b) === true) {
    // do some stuff
}
else {
    // do other stuff
}

Как уже указывалось , в ситуациях, когда существует много вариантов и типов, может быть полезным выражение switch. Однако такая ситуация была бы редкостью.

2 голосов
/ 16 декабря 2010

Для ясности этот случай выглядит оскорбительным, но, поскольку Javascript в принципе не является строго типизированным, он может быть полезен, если вы не можете контролировать ввод:

switch (foo)
{
    case true:
        // whatever
        break;
    case false:
        // whatever
        break;
    default:
        // FOO IS NOT A BOOLEAN, DO SOMETHING ELSE!
        break;
}

А также смешанный случай Эндрю. Это немного безопаснее, чем простой if / else, и более кратко, чем какая-то логическая проверка, а затем if / else.

1 голос
/ 16 декабря 2010

Обновлено после комментария и ответа Энди Нет никакой разницы (в вашем примере), но в вашем примере блок if более читабелен и в этом случае имеет больше смысла (на мой взгляд).

switch в утверждении, которое оценивается как boolean, кажется неправильным только потому, что всегда будет только два случая (true и false), и по этой причине я рекомендую if блок вместо.

switch имеет больше смысла, когда вы оцениваете переменную, которая может иметь много значений:

switch(fruitType) {
    case 'Apple':
    // Apple Code
    break;
    case 'Orange':
    // Orange Code
    break;
    // etc...
    default: // other fruit
    break;
}

Надеюсь, это поможет!

0 голосов
/ 16 декабря 2010

Ваш пример не показывает этого, но я думаю, что это может сделать для более краткого кода, если вы хотите использовать падение (т.е. без перерыва) в первом case, в зависимости от ситуации.

Это также может быть приличной конструкцией, если вы реализуете что-то таким образом, который предвидит потенциальные изменения и хотите иметь минимальную переработку (например, хотите сохранить действия такими же, просто переделывая логику выбора).

0 голосов
/ 16 декабря 2010

В вашем примере разницы нет.Но в зависимости от того, как определены a и b, вы можете добавить больше операторов switch позже, например:

var a = false, b = null;
switch (a || b) {
  case true:
    // do some stuff
  break;
  case null:
    // do some stuff
  break;
  default:
    // do other stuff
  break;
}

Кроме этого, это в основном вопрос предпочтения кодирования.*

...