Может ли тернарный оператор быть эквивалентным короткому замыканию с логическими операторами?

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

let x = "", y = 123;
x && alert("foo"); // ""
y || alert("bar") // 123

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

Но в конечном итоге это не что иное, как условное ветвление, которое легко достигается с помощью тернарного оператора:

x ? alert("foo") : x; // ""
y ? y : alert("bar"); // 123

Это более читабельно и так же лаконично. Есть ли причина использовать свойство короткого замыкания логических операторов, кроме иллюстративного термина?


person Iven Marquardt    schedule 02.02.2016    source источник
comment
&& и || были разработаны как специальные формы & и |, оптимизированные для конкретных случаев. Для людей, привыкших думать в терминах логической арифметики, x ? y : x вместо x && y было бы гораздо менее читабельным, как и проблема с побочными эффектами, и их не совсем то же самое, что в C, от которого Javascript унаследовал их.   -  person Jon Hanna    schedule 03.02.2016


Ответы (1)


Это правда (ну, почти правда), что

x ? x : y

логически эквивалентен

x || y

Однако они не эквивалентны тому, что происходит при запуске кода. В случае ? : подвыражение x может быть вычислено дважды. В x || y он определенно оценивается только один раз. Для простых ссылок на переменные это не имеет значения, но если x является вызовом функции, это может повлиять на поведение и, безусловно, повлияет на производительность.

(Тот факт, что одно из выражений может быть вычислено дважды, - это то, что я имел в виду под словом «почти» в первом предложении.)

person Pointy    schedule 02.02.2016
comment
Вот и все! Я знал, что что-то упустил. Спасибо! - person Iven Marquardt; 03.02.2016
comment
Мне было бы интересно узнать, что такое «почти истинная» часть логической эквивалентности. Бывают ли обстоятельства, когда одно из выражений истинно, а другое - нет? - person mrmcgreg; 03.02.2016
comment
Для таких вещей, как опции || {} гораздо удобнее использовать идиоматику || чем использовать тернарный оператор. - person m4ktub; 03.02.2016
comment
@mrmcgreg - это исполнение; извините, я не сказал этого ясно. - person Pointy; 03.02.2016
comment
Почему движок не может это оптимизировать? Из-за возможных эффектов сайта в функции? - person Iven Marquardt; 03.02.2016
comment
Вполне возможно, что движок его оптимизирует, если он оптимизирует любые побочные эффекты или гарантирует, что их нет. - person Jon Hanna; 03.02.2016
comment
@JonHanna, это правда, но такой анализ может быть довольно сложным. Если подвыражение включает вызов функции, действительно маловероятно, что среда выполнения может гарантировать, что код не ожидает побочного эффекта. Напомним, что у материала оптимизации JavaScript нет бюджета времени чего-то вроде оптимизирующего компилятора C ++. - person Pointy; 03.02.2016
comment
@JonHanna Я полагаю, что побочные эффекты являются причиной того, что ленивая оценка не работает в Javascript. Это хороший пример. - person Iven Marquardt; 03.02.2016
comment
Ага, а вот ответить почему не работает двигатель? мы должны начать с того, кто сказал, что не может ?. Я не удивлюсь, если некоторые будут делать это, когда операнд представляет собой единственную переменную, или если некоторые будут делать это, когда операнд является литералом. Я не удивлюсь, если ни один из них не сделает этого, потому что это не будет большим хитом. - person Jon Hanna; 03.02.2016