Сокращенный тернарный оператор Javascript

104

Я знаю, что в php 5.3 вместо использования этого избыточного синтаксиса тернарного оператора:

startingNum = startingNum ? startingNum : 1

... мы можем использовать сокращенный синтаксис для наших тернарных операторов, где это применимо:

startingNum = startingNum ?: 1

И я знаю о тернарном операторе в javascript:

startingNum = startingNum ? startingNum : 1

... но есть ли стенография?

Веб-дизайнер
источник

Ответы:

179
var startingNumber = startingNumber || 1;

Что-то вроде того, что вы ищете, где оно по умолчанию, если не определено?

var foo = bar || 1; // 1
var bar = 2;
foo = bar || 1;     // 2

Кстати, это работает для множества сценариев, включая объекты:

var foo = bar || {}; // secure an object is assigned when bar is absent
Брэд Кристи
источник
Действительно, сегодня утром подпрыгивал. Исправлено, но спасибо, что заметили.
Брэд Кристи,
1
Разве вы не имеете в виду ||вместо ???
Rocket Hazmat
2
Спасибо! Ты сделал это. На самом деле я использую объект в этом случае. :)
Web_Designer
8
Для всех, кому интересно, это работает, потому что ||оператор JS не возвращает true или false, он возвращает первое «истинное» значение. Скажем , у вас есть , val0и , val1как undefinedи val2есть 2, val3есть 3. val0 || val1 || val2 || val3вернется 2, так как это первое «истинное» значение.
Джейк Т.
2
Разве эта идиома не антипаттерн? Что, если вы передадите 0 или пустую строку, выражение «ИЛИ» пропустит ее и будет использовать значение по умолчанию, где вы действительно хотели 0 или пустую строку.
Paul Trzyna
24

|| вернет первое истинное значение, с которым столкнется, и поэтому может использоваться как оператор объединения, аналогично C # ??

startingNum = startingNum || 1;
Адам Рэкис
источник
Мне ваше объяснение нравится больше, чем другие
ajax333221
12

Да, есть:

var startingNum = startingNum || 1;

В общем, expr1 || expr2работает следующим образом (как указано в документации ):

Возвращает, expr1если его можно преобразовать в true; в противном случае возвращается expr2. Таким образом, при использовании со Booleanзначениями ||возвращает, trueесли любой из операндов true; если оба false, возвращается false.

Тадек
источник
Разве не правильнее сказать if a is truthyvs. if a is evaluated to true?
JaredPar
3
@JaredPar: Чтобы избежать двусмысленности, я заменил свое первоначальное подробное объяснение на объяснение из Mozilla Developer Network. Он должен быть менее двусмысленным.
Tadeck
2
var startingNum = startingNum || 1;

В этом случае вы можете использовать оператор ИЛИ.

Даниэль
источник
2
startingNum = startingNum || 1

Если у вас есть условие с нулем, например

startingNum = startingNum ? startingNum : null

ты можешь использовать '&&'

startingNum = startingNum && startingNum
a2441918
источник
Но не будет anything && nullоценивать значение null, если anythingэто не ложь?
Петруза 02
Да, если что-то правда, оно оценивается как null. Если это ложь, оценивается как ложное значение
a2441918
1

Приведенные выше ответы верны. В JavaScript следующий оператор:

startingNum = startingNum ? otherNum : 1

можно выразить как

startingNum = otherNum || 1

Другой сценарий, не описанный здесь, - это если вы хотите, чтобы значение возвращало false, если оно не соответствует. Сокращение в JavaScript для этого:

startingNum = startingNum ? otherNum : 0

Но это можно выразить как

startingNum = startingNum && otherNum

Просто хотел осветить другой сценарий на случай, если другие будут искать более общий ответ.

Джон Пейс
источник
есть ли сокращение для чего-то вроде этого: x = innerWidth * 0.0375 > 24 ? innerWidth * 0.0375 : 24???
oldboy
@Anthony Нет, потому что это innerWidth * 0.0375 > 24отличается от той if trueчасти, которая есть innerWidth * 0.0375. Сокращение можно использовать только в том случае, если expression to be evaluatedи if trueявляются одинаковыми значениями. То же самое, почему вы не можете вести стенографию x = someBoolean ? 'Heck yea!' : 'No way!'.
deedub
@deedub ну, на самом деле, есть "стенография" (если вы это так называете), которая будетMath.max(innerWidth * 0.0375, 24)
oldboy
@Anthony Вы бы не назвали это так;) Но Math.maxв вашем случае работает лучше, чем тернарный оператор.
deedub
1
" startingNum = startingNum ? otherNum : 1можно выразить как startingNum = otherNum || 1" неверно. я только что проверил это
oldboy
0

Чтобы сделать тернар вроде:

boolean_condition ? true_result : false_result

в javascript вы можете:

(boolean_condition && true_result ) || false_result;

Пример:

(true && 'green') || 'red';
=> "green"
(false && 'green') || 'red';
=> "red"
xxjjnn
источник
ооочень x = innerWidth * 0.0375 > 24 ? innerWidth * 0.0375 : 24стало бы (innerWidth * 0.0375 > 24 && innerWidth * 0.0375) || 24?? есть ли сокращение, чтобы мне не приходилось повторять innerWidth * 0.0375, кроме как присвоить его переменной ???
oldboy
1
В этом случае Math.max( innerWidth * 0.0375 , 24 )будет работать элегантно. В более общем случае было бы хорошо создать описательный метод с названием, например, somethingifiedInnerWidth, который улучшает читаемость, а не создавать переменную. Хотя в некоторых случаях было бы более читабельно иметь переменную (с таким описательным именем), поэтому в будущем возникает вопрос «почему она умножается на это?» не возбуждается.
xxjjnn
вау даже не знал, что ты можешь дать второй аргумент Math.max. супер шикарное решение !!
oldboy