Javascript Тройной Оператор против ||

17

Ранее я просматривал какой-то код node.js и заметил, что тот, кто его написал, предпочитает следующий синтаксис:

var fn = function (param) {
    var paramWithDefault = null == param ? 'Default Value' : param;
}

Над тем, что я считаю более кратким:

var fn = function (param) {
    var paramWithDefault = param || 'Default Value';
}

Мне было интересно, если вторая форма на самом деле является более социально приемлемым синтаксисом JavaScript, я видел это в дикой природе больше раз, чем троичный оператор для этой цели.

Я отмечаю, что в первом примере он использует двойные равные (а не тройные равные), что означает, что он будет считать «неопределенный» как нулевой, что уменьшит одно влияние, о котором я мог подумать. Однако во многих местах я читал, что == является довольно злым оператором в JavaScript (JSLint очень против этого, IIRC).

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

Ответы:

17

Потому что этот код будет иметь значение «Значение по умолчанию» каждый раз, когда вы передаете 0, «», false или какое-либо другое ложное значение.

function fn(param) {
  var paramWithDefault = param || 'Default Value';
  return paramWithDefault;
}

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

Питер Смит
источник
Вы должны использовать только null coalesce для объекта, и если объект определен, то это не сработает. Возможно, за исключением пустой строки.
Malfist
4
Нулевое сравнение - это хороший момент, который может быть довольно неожиданным.
Эд Джеймс
1
+1 - именно из-за этой проблемы Python (в конце концов) добавил синтаксис «x if y else z». Эта семантика для логических операторов довольно распространена, и одни и те же общие ошибки, как правило, возникают, когда идиомы полагаются на них при выполнении операторов условного выбора.
Steve314
только не забудьте поместить ваши конструкции в круглые скобки, если вы будете использовать их вместе, var txt = 'Hello, ' + (user_name||'User') + '!';будет работать конкатенация строк , но без скобок - вы получите undefined. jsfiddle.net/4mFAB/1
c69
7

Что вам действительно нужно, так это нулевой оператор объединения. Но, увидев, что в javascript его нет, программисты обычно используют '||' стоять за это.

Тем не менее, оба вполне разумны. Для тех, кто не понимает, что такое оператор слияния, тернарный оператор, вероятно, будет более понятен.

Malfist
источник
Другим связанным оператором является оператор Icon, записанный IIRC как «else». Это распознает специальный результат «неудача» из первого аргумента и использует второй аргумент в этом случае в качестве альтернативы. Я бы хотел, чтобы Pythons «x if y else z» были реализованы с использованием двух отдельных операторов - оператора бинарного утверждения «if» и оператора «else», похожего на иконку, - чтобы эти два оператора могли использоваться независимо. Тем не менее, Icon не поддерживает этот стиль, вместо этого делает что-то странное с относительными операторами.
Steve314
@ Steve314: В Python есть то, что вы хотели: отдельный оператор else [false-part, true-part]с отдельным оператором if, [..][bool(condition)]объединенным в [false-part, true-part][bool(condition)]. Если вы хотите ленивого поведения, вы можете просто лямбда-истину и ложь.
Ли Райан