Тернарні оператори в JavaScript без “Else”


149

Мені завжди доводилося ставити nullв інших умовах, у яких немає нічого. Чи є все-таки навколо цього? Напр

condition ? x = true : null;

в основному, чи є спосіб зробити:

condition ? x = true;

Тепер це відображається як синтаксична помилка

FYI, ось справжній приклад коду:

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

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

1
matt, ваша відповідь найкраща, але це не відповідь, це коментар!
Cheeso

Метт, мій АКТУАЛЬНИЙ код:! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; коротший, кращий спосіб написати це?
Оскар Годсон

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

було б краще уникати присвоєння особи, тому це має бути лише умовою:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Михайло Малостанідіс

Відповіді:


226

Перш за все, потрійний вираз не є заміною конструкції if / else - його еквіваленту конструкції if / else, яка повертає значення. Тобто, якщо "if / else" є кодом, потрійний вираз - це вираз , тобто він повертає значення.

Це означає кілька речей:

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

Коротше кажучи - «правильне» використання потрійного виразу є

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
пустота (умова && x = вірно) - це виглядає чудово, але, здається, викидає помилку "недійсне призначення ліворуч"
Євген Тюрін

1
void (умова && (x = вірно)) // зберігає завдання окремо від першого значення
diamondsea

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

2
Чи можете ви пояснити, що ви маєте на увазі під "не пройти перевірку"? Я не розумію, навіщо слід обертати цей вираз void(). Дякую.
gilad mayani

20

Ні, для цього потрібні три операнди. Тому їх називають потрійними операторами.

Однак для того, що ви є своїм прикладом, ви можете зробити це:

if(condition) x = true;

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

if(condition) { x = true; }

Редагувати. Тепер, коли ви згадуєте фактичний код, до якого відноситься ваше запитання:

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

1
Можна, але не слід. Принаймні, не без фігурних дужок навколо нього - це дуже помилка.
Конерак

1
це правда? Я зрозумів, що головна причина, що вимагає отримання кучериків, полягає в тому, що вони полегшують життя jslint.
Cheeso

@Cheeso це помилка в сенсі рефакторингу. ВИ повернетесь, щоб додати більше справ у випадку справжнього стану, не розуміючи, що там немає фігурних дужок. Новий код завжди буде виконуватись, а не тоді, коли є істинним.
Метс 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оцінено як істинне, а obj.find('img').width()+'px'значення - інакше.

Докладніше див. Оцінка логічного оператора короткого замикання .



5

Ви могли написати

x = condition ? true : x;

Отже, x є немодифікованим, коли умова хибна.

Це тоді рівнозначно

if (condition) x = true

Редагувати:

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

Є кілька альтернатив - я не кажу, що це краще / гірше - просто альтернативи

Передача нуля як третій параметр працює, оскільки наявне значення є нульовим. Якщо ви рефакторируете і зміните умову, то існує небезпека, що це більше не відповідає дійсності. Передаючи існуюче значення як другий вибір у потрійних гвардіях проти цього:

!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.