Тернарные операторы в JavaScript без «остального»


149

Мне всегда приходилось ставить nullусловия, в которых ничего нет. Есть ли что-нибудь вокруг этого? Например

condition ? x = true : null;

в принципе, есть ли способ сделать:

condition ? x = true;

Теперь это проявляется как синтаксическая ошибка

К вашему сведению, вот пример кода:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;

21
использование троичного подобия condition ? x = true : null;должно быть записано как x = (condition ? true : null);. Кроме того, в javascript nullоценивается как false, так что в этом случае вы могли бы x = (condition);и достичь того же результата.
Мэтт С

1
Мэтт, ваш ответ лучше, но это не ответ, это комментарий!
Cheeso

Мэтт, мой фактический код:! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; короче, лучший способ написать это?
Оскар Годсон

2
defaults.slideshowWidth = defaults.slideshowWidth || obj.find ('img'). width () + 'px';
Кеннебек

было бы лучше избегать присвоения личности, поэтому это должно быть просто условием:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Михаил Малостанидис,

Ответы:


226

Прежде всего, троичное выражение не является заменой для конструкции if / else - это эквивалент конструкции if / else, которая возвращает значение. То есть предложение if / else является кодом, троичное выражение является выражением , означающим, что оно возвращает значение.

Это означает несколько вещей:

  • используйте троичные выражения только тогда, когда у вас есть переменная слева от =которой должно быть присвоено возвращаемое значение
  • Используйте троичные выражения только тогда, когда возвращаемое значение должно быть одним из двух значений (или используйте вложенные выражения, если это подходит)
  • каждая часть выражения (после? и после:) должна возвращать значение без побочных эффектов (выражение x = trueвозвращает истину, так как все выражения возвращают последнее значение, но также меняет x без того, чтобы x оказывал какое-либо влияние на возвращаемое значение)

Короче говоря, «правильное» использование троичного выражения

var resultofexpression = conditionasboolean ? truepart: falsepart;

Вместо вашего примера condition ? x=true : null ;, где вы используете троичное выражение для установки значения x, вы можете использовать это:

 condition && (x = true);

Это все еще выражение и, следовательно, может не пройти валидацию, поэтому еще лучший подход будет

 void(condition && x = true);

Последний пройдет проверку.

Но опять же, если ожидаемое значение является логическим, просто используйте результат самого выражения условия

var x = (condition); // var x = (foo == "bar");

ОБНОВЛЕНИЕ В отношении вашего образца это, вероятно, более уместно:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

4
великолепно ТАК, не позволяя редактировать, чтобы исправить i/elseопечатку, так как недостаточно символов.
роса

1
void (условие && x = true) - это выглядит великолепно, но, похоже,
выдает

1
void (условие && (x = true)) // сохраняет назначение отдельно от первого значения
diamondsea

4
Однако, это не интуитивно понятно, особенно для разработчиков, не привыкших к этому стилю. Вы можете написать это так же легко и просто, как: if (условие) {x = true; }
diamondsea

2
Не могли бы вы объяснить, что вы подразумеваете под "может не пройти проверку"? Я не понимаю, почему нужно обернуть выражение в void(). Спасибо.
Гилад Майяни

20

Нет, для этого нужны три операнда. Вот почему их называют троичными операторами.

Однако, для примера, вы можете сделать это:

if(condition) x = true;

Хотя безопаснее иметь фигурные скобки, если вам нужно добавить более одного утверждения в будущем:

if(condition) { x = true; }

Изменить: Теперь, когда вы упоминаете фактический код, в котором ваш вопрос относится к:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }

1
Вы можете, но не должны. По крайней мере, без фигурных скобок вокруг него - это очень ошибка.
Конерак

1
это правда? Я понял, что главная причина, по которой требуются кудри, заключается в том, что они облегчают жизнь Джлинт.
Cheeso

@ Че, это ошибка в смысле рефакторинга. Вы возвращаетесь, чтобы добавить больше, чтобы сделать в случае истинного условия, не понимая, что там нет фигурных скобок. Новый код всегда будет выполняться, а не в случае, когда истина.
Matt S

Нет, я знаю, мне просто нравится писать условные выражения без таких дополнений, как if () {} else {}, когда оно равно просто?:;
Оскар Годсон

3
Честно говоря, я никогда не знал разработчиков, более испуганных использованием языка, чем Javascript: - Мне бы не хотелось, чтобы кто-то говорил мне, что я не должен использовать фигурные скобки. Я часто их опускаю, и у меня никогда не бывает больше проблем, чем если бы я случайно пропустил фигурную скобку.
Энди Э

12

Чаще люди используют логические операторы для сокращения синтаксиса операторов:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

Но в вашем конкретном случае синтаксис может быть еще проще

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Этот код вернет defaults.slideshowWidthзначение, если значение defaults.slideshowWidthравно true иobj.find('img').width()+'px' значение иначе.

См. Короткое замыкание Оценка логических операторов для деталей.



5

Вы могли бы написать

x = condition ? true : x;

Так что х не изменяется, когда условие ложно.

Это эквивалентно

if (condition) x = true

РЕДАКТИРОВАТЬ:

!defaults.slideshowWidth 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : null 

Есть несколько альтернатив - я не говорю, что они лучше / хуже - просто альтернативы

Передача нулевого значения в качестве третьего параметра работает, поскольку существующее значение равно нулю. Если вы выполните рефакторинг и измените условие, то есть опасность, что это больше не так. Передача существующего значения в качестве 2-го выбора в тройной страже против этого:

!defaults.slideshowWidth = 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : defaults.slideshowwidth 

Безопаснее, но, возможно, не так приятно смотреть, и больше печатать. На практике я бы наверное написал

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'

Некоторый живой код (в любом случае, чтобы избавиться от нуля в этом?):! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null;
Оскар Годсон

2

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

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

станет :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Это более понятно, это больше стиль "javascript".



1

Для использования тернарного оператора без указания внутри массива или объявления объекта вы можете использовать оператор распространения ES6 ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

И для объектов:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

первоисточник

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.