Пример тернарного оператора JavaScript с функциями

91

Я использую jQuery 1.7.1

Я только начинаю использовать тернарный оператор JavaScript для замены простых операторов if / else. Мне удалось добиться этого в нескольких местах. Я был удивлен, когда мне удалось заставить что-то еще работать, когда я был уверен, что это не так, но я все равно попробовал.

Вот исходное заявление:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    if (IsChecked == true){
        removeItem($this);
    } else {
        addItem($this);
    }
}

Вот та же функция, использующая тернарный оператор:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    (IsChecked == true) ? removeItem($this) : addItem($this);
}

Я был удивлен, потому что все используемые мной примеры просто устанавливали такие переменные:

x = (1 < 2) ? true : false;

У меня вопрос, является ли это «нормальным» использованием и будет ли это работать в большинстве версий JavaScript? Где он потерпит неудачу? Есть ли другие менее очевидные способы его использования?

ОБНОВЛЕНИЕ - Спасибо за совет "реального мира" !!!

Я использую это как свою функцию:

function updateItem() {
    $this = $(this);
    $this.hasClass("IsChecked") ? removeItem($this) : addItem($this);
}
Эвик Джеймс
источник
Это нормально и будет работать нормально .. В общем, при использовании тернарных операторов читабельность затруднена, но в вашем случае все выглядит нормально.
Сельвакумар Арумугам
1
Хм ... вы также можете сделать это, поскольку они оба принимают одни и те же аргументы (IsChecked ? removeItem : addItem)($this). Однако, отвечая на ваш вопрос, да, это нормально, и нет ничего плохого в использовании тернарных операторов, если они не ухудшают ремонтопригодность или удобочитаемость в ситуации, когда это необходимо. jsfiddle.net/vsB3f
Кевин Б.
if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)это правильный путь. Тернарный оператор предназначен не для подобных случаев, а для таких вещей foo(isChecked ? 'bar' : meow());(то есть, когда вы заботитесь о «возвращаемом значении» того, что вы делаете в блоках then / else)
ThiefMaster
1
В вашем примере пропустите первую строку в пользу этого: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); я могу понять ваш код как есть в одной строке, поэтому он соответствует моему эмпирическому правилу (см. Сообщение ниже). Работает для меня.
Surreal Dreams

Ответы:

189

Хех, в вашем вопросе есть несколько интересных вариантов использования тернарного синтаксиса; Мне последний нравится больше всего ...

x = (1 < 2) ? true : false;

Использование тернарности здесь совершенно не нужно - вы можете просто написать

x = (1 < 2);

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

(IsChecked == true) ? removeItem($this) : addItem($this);

Просто как:

(IsChecked) ? removeItem($this) : addItem($this);

Фактически, я бы также удалил IsCheckedвременное, что оставляет вам:

($this.hasClass("IsChecked")) ? removeItem($this) : addItem($this);

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

Джонни Ривз
источник
обратите внимание, что вы можете избегать использования прописных букв в именах классов (IsChecked становится проверенным) stackoverflow.com/questions/1547986/…
Адриен Бе
JS имеет первоклассные функции:($this.hasClass("isChecked") ? removeItem : addItem)($this)
Clojure, в основном,
22

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

Полный формат if / then / else используется практически для всего. Это особенно популярно, если вы входите в большие блоки кода в каждой ветке, у вас есть многоразветвленное дерево if / else или несколько else / if в длинной строке.

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

Хорошие идеи:

this > that ? alert(this) : alert(that);  //nice and short, little loss of meaning

if(expression)  //longer blocks but organized and can be grasped by humans
{
    //35 lines of code here
}
else if (something_else)
{
    //40 more lines here
}
else if (another_one)  /etc, etc
{
    ...

Менее хорошо:

this > that ? testFucntion() ? thirdFunction() ? imlost() : whathappuh() : lostinsyntax() : thisisprobablybrokennow() ? //I'm lost in my own (awful) example by now.
//Not complete... or for average humans to read.

if(this != that)  //Ternary would be done by now
{
    x = this;
}
else
}
    x = this + 2;
}

Действительно основное правило - вы можете понять все это так же хорошо или лучше на одной линии? Тернар в порядке. В противном случае расширьте его.

Сюрреалистические мечты
источник
7

В опубликованном вами примере нет ничего особенного.

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

Подумайте об этом так:

var x = (1 < 2) ? true : false;

Также может быть записано как:

var x = (1 < 2) ? getTrueValue() : getFalseValue();

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

(1 < 2) ? getTrueValue() : getFalseValue();

Теперь просто замените их любыми произвольными функциями, и у вас останется что-то вроде вашего примера:

(1 < 2) ? removeItem($this) : addItem($this);

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

x = (1 < 2);  // x will be set to "true"
Джефф Б.
источник
7

Я также хотел бы добавить кое-что от себя.

Другой возможный синтаксис для вызова функций с тернарным оператором:

(condition ? fn1 : fn2)();

Это может быть удобно, если вам нужно передать один и тот же список параметров обеим функциям, поэтому вам нужно записать их только один раз.

(condition ? fn1 : fn2)(arg1, arg2, arg3, arg4, arg5);

Вы можете использовать тернарный оператор даже с именами функций-членов, что мне лично очень нравится для экономии места:

$('.some-element')[showThisElement ? 'addClass' : 'removeClass']('visible');

или

$('.some-element')[(showThisElement ? 'add' : 'remove') + 'Class']('visible');

Другой пример:

var addToEnd = true; //or false
var list = [1,2,3,4];
list[addToEnd ? 'push' : 'unshift'](5);
Бартломей Залевски
источник
6

Если вы собираетесь вкладывать тернарные операторы, я считаю, что вам нужно сделать что-то вроде этого:

   var audience = (countrycode == 'eu') ? 'audienceEU' :
                  (countrycode == 'jp') ? 'audienceJP' :
                  (countrycode == 'cn') ? 'audienceCN' :
                  'audienceUS';

Писать / читать намного эффективнее, чем:

var audience = 'audienceUS';
if countrycode == 'eu' {
   audience = 'audienceEU';
} else if countrycode == 'jp' {
   audience = 'audienceJP';
} else if countrycode == 'cn' {
   audience = 'audienceCN';
}

Как и во всем хорошем программировании, пробелы делают все приятным для людей, которым приходится читать ваш код после того, как вы закончите работу над проектом.

Сэм В
источник
6
Категорически не согласен с вашим вышеупомянутым комментарием о том, что вложенные троичные файлы легче читать и отлаживать. Лично я предпочел бы, чтобы вложенный блок else / if заменялся либо таблицей поиска, либо оператором switch.
JonnyReeves
@JonnyReeves согласился - обычно вложенный тернарный синтаксис лучше всего использовать при проверке различных условий (например, по модулю чисел )
AlexFoxGill
2

Я знаю, что на вопрос уже дан ответ.

Но позвольте мне добавить здесь один момент. Это не только случай истинного или ложного. Увидеть ниже:

var val="Do";

Var c= (val == "Do" || val == "Done")
          ? 7
          : 0

Здесь, если val равно Do или Done, то c будет 7, иначе оно будет равно нулю. В этом случае c будет 7.

На самом деле это еще одна перспектива этого оператора.

Химаншу Тивари
источник