Что означает конструкция x = x || y?
Я отлаживаю некоторые JavaScript, и не могу объяснить, что это ||
делает?
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
может кто-нибудь дать мне подсказку, почему этот парень использует var title = title || 'ERROR'
? Я иногда вижу его без var
декларации, а также.
11 ответов:
значит
title
аргумент является необязательным. Так что если вы вызываете метод без аргументов, он будет использовать значение по умолчанию"Error"
.это стенография для записи:
if (!title) { title = "Error"; }
этот вид стенографического трюка с булевыми выражениями также распространен в Perl. С выражением:
a OR b
он оценивает в
true
еслиa
илиb
иtrue
. Так что еслиa
это правда, что вам не нужно проверятьb
на всех. Это называется короткое замыкание булевой оценки так:var title = title || "Error";
в основном проверяет, является ли
title
значениеfalse
. Если это так, он "возвращает""Error"
, в противном случае она возвращаетtitle
.
что такое оператор двойной трубы (
||
)?оператор двойной трубы (
||
) является логическоеOR
оператор . В большинство языков это работает следующим образом:
- если первое значение
false
, он проверяет второе значение. Если этоtrue
возвращаетtrue
и еслиfalse
возвращаетfalse
.- если первое значение
true
, он всегда возвращаетtrue
, несмотря ни на что второе значение.так что в основном это работает как эта функция:
function or(x, y) { if (x) { return true; } else if (y) { return true; } else { return false; } }
если вы все еще не понимаете, посмотрите на эту таблицу:
| true false ------+--------------- true | true true false | true false
другими словами, это только ложь, когда оба значения ложны.
как это отличается в JavaScript?
JavaScript немного отличается, потому что это слабо типизированным языком. В данном случае это означает, что вы можете использовать
||
оператор со значениями, которые не логические значения. Хотя это не имеет смысла, вы можете использовать этот оператор, например, с функцией и объектом:(function(){}) || {}
что там происходит?
если значения не являются логическими, JavaScript делает неявный разговор в boolean. Это означает, что если значение falsey (например
0
,""
,null
,undefined
(см. Также все ложные значения в JavaScript)), это будет рассматриваться какfalse
; в противном случае он рассматривается какtrue
.так что приведенный выше пример должен дать
true
, потому что пустая функция-истина. Ну, это не так. Он возвращает пустой функции. Это потому, что JavaScript-это||
оператор не работает, как я писал в начале. Он работает следующим образом:
- если первое значение falsey возвращает второе значение.
- если первое значение истина возвращает первый значение.
удивлен? На самом деле, это "совместимо" с традиционным
||
оператора. Это может быть записано как следующая функция:function or(x, y) { if (x) { return x; } else { return y; } }
если вы передаете истинное значение как
x
возвращаетx
, то есть истинная ценность. Так что если вы используете его позже вif
статья:(function(x, y) { var eitherXorY = x || y; if (eitherXorY) { console.log("Either x or y is truthy."); } else { console.log("Neither x nor y is truthy"); } }(true/*, undefined*/));
вы получаете
"Either x or y is truthy."
.если
x
был falsey,eitherXorY
будетy
. В этом случае вы получите"Either x or y is truthy."
еслиy
было правдиво; в противном случае вы получите"Neither x nor y is truthy"
.вопрос
теперь, когда вы знаете, как
||
оператор работает, вы, вероятно, можете разобрать сами, что делаетx = x || y
значит. Еслиx
- истина,x
назначенаx
, так что на самом деле ничего не происходит; в противном случаеy
назначенаx
. Он обычно используется для определения параметров по умолчанию в функциях. Тем не менее, это часто считается плохая практика программирования, потому что это предотвращает передачу ложного значения (что не обязательноundefined
илиnull
) в качестве параметра. Рассмотрим следующий пример:function badFunction(/* boolean */flagA) { flagA = flagA || true; console.log("flagA is set to " + (flagA ? "true" : "false")); }
это выглядит действительно на первый взгляд. Однако, что произойдет, если вы прошли
false
какflagA
параметр (так как он логический, т. е. может бытьtrue
илиfalse
)? он сталtrue
. в этом примере невозможно установитьflagA
доfalse
.было бы лучше явно проверьте, является ли
flagA
иundefined
, вот так:function goodFunction(/* boolean */flagA) { flagA = typeof flagA !== "undefined" ? flagA : true; console.log("flagA is set to " + (flagA ? "true" : "false")); }
хотя это дольше, это всегда работает, и это легче понять.
вы также можете использовать синтаксис ES6 для параметров функции по умолчанию, но обратите внимание, что он не работает в старых браузерах (например, IE). Если вы хотите поддерживать эти браузеры, вы должны транспилировать свой код с помощью Бабель.
см. также логические операторы на MDN.
Если заголовок не задан, используйте 'ERROR' в качестве значения по умолчанию.
более общий:
var foobar = foo || default;
читает: установите foobar в
foo
илиdefault
. Вы можете даже цепочку это много раз:var foobar = foo || bar || something || 42;
объяснить это немного больше...
The
||
оператор логического-or
оператора. Результат истинен, если первая часть истинна, и это истинно, если вторая часть истинна, и это истинно, если обе части истинны. Для ясности, вот она в таблице:X | Y | X || Y ---+---+-------- F | F | F ---+---+-------- F | T | T ---+---+-------- T | F | T ---+---+-------- T | T | T ---+---+--------
теперь заметьте что-то здесь? Если
X
верно, результат всегда верен. Так что если мы знаем, чтоX
это правда, мы не должны проверятьY
на всех. Многие языки таким образом реализуют "короткое замыкание" вычислители для логического-or
(и логично-and
идет с другой стороны). Они проверяют первый элемент, и если это правда, они вообще не утруждают себя проверкой второго. Результат (в логических терминах) тот же, но с точки зрения выполнения есть потенциально огромная разница, если второй элемент дорого вычислить.так какое это имеет отношение к вашему примеру?
var title = title || 'Error';
давайте посмотрим на это. Элемент
title
элемент передать в вашу функцию. В JavaScript, если вы не передаете параметр, он по умолчанию имеет нулевое значение. Также в JavaScript, если ваша переменная является нулевым значением, логические операторы считают ее ложной. Поэтому, если эта функция вызывается с заданным заголовком, Это не ложное значение и, таким образом, присваивается локальной переменной. Если, однако, ему не задано значение, оно является нулевым значением и, следовательно, ложным. Логическое-or
оператор затем вычисляет второе выражение и возвращает 'Error' вместо. Так что теперь локальной переменной присваивается значение 'Error'.это работает из-за реализации логических выражений в JavaScript. Он не возвращает правильное логическое значение (
true
илиfalse
) но вместо этого возвращает значение, которое было дано в соответствии с некоторыми правилами относительно того, что считается эквивалентнымtrue
и что считается эквивалентнымfalse
. Найдите ссылку на JavaScript, чтобы узнать, что JavaScript считает истинным или ложным в boolean контексты.
двойная труба означает логическое "или". Это не совсем тот случай, когда "параметр не установлен", так как строго в javascript, если у вас есть такой код:
function foo(par) { }
вызывает
foo() foo("") foo(null) foo(undefined) foo(0)
не эквивалентны.
Double pipe ( | | ) приведет первый аргумент к boolean, и если результирующее boolean истинно - выполните назначение, иначе он назначит правую часть.
это имеет значение, если вы проверяете для параметра unset.
допустим, у нас есть функция setSalary, которая имеет один необязательный параметр. Если пользователь не предоставляет параметр, то следует использовать значение по умолчанию 10.
если вы делаете проверку, как это:
function setSalary(dollars) { salary = dollars || 10 }
это даст неожиданный результат по вызову, как
setSalary(0)
Он все равно установит 10 после потока, описанного выше.
в основном он проверяет, если значение перед || оценивается в true, если да, то он принимает это значение, если нет, то он принимает значение после ||.
значения, для которых он будет принимать значение после || (насколько я помню):
- неопределено
- ложные
- 0
- " (нулевая или нулевая строка)
оператор двойной трубы
этот пример полезен?
var section = document.getElementById('special'); if(!section){ section = document.getElementById('main'); }
можно
var section = document.getElementById('special') || document.getElementById('main');
пока Клетус' ответ правильно, я чувствую, что более подробно следует добавить в отношении "оценивает ложь" в JavaScript.
var title = title || 'Error'; var msg = msg || 'Error on Request';
не просто проверяет, если заголовок/msg был предоставлен, но и если любой из них ложь. т. е. одно из следующих действий:
- ложно.
- 0 (ноль)
- "" (пустая строка)
- null.
- не определено.
- NaN (специальное числовое значение, означающее Not-a-Number!)
в строку
var title = title || 'Error';
если название является правдивым (т. е. не ложным, поэтому title = "titleMessage" и т. д.) затем логический оператор OR ( / / ) нашел одно значение true, что означает, что он оценивает значение true, поэтому он закорачивает и возвращает истинное значение (заголовок).
Если заголовок является ложным (т. е. один из списка выше), то логический оператор OR (||) нашел значение "false", и теперь необходимо оценить другую часть оператора, 'Error', которая оценивается как true, и, следовательно, возвращается.
также казалось бы (после некоторых быстрых экспериментов с консолью firebug), если обе стороны оператора оценивают false, он возвращает второй оператор "falsy".
т. е.
return ("" || undefined)
возвращает undefined, это, вероятно, позволит вам использовать поведение, заданное в этом вопросе при попытке по умолчанию заголовок/сообщение "". т. е. после работает
var foo = undefined foo = foo || ""
foo будет установлен в""
var name = false || "Mohsen"; # name equals to Mohsen var family = true || "Alizadeh" # family equals to true
это означает, что если левая сторона оценивается как истинный оператор, он будет завершен, а левая сторона будет возвращена и назначена переменной. в других случаях правая сторона будет возвращена и назначена.
и оператор имеет противоположную структуру, как показано ниже.
var name = false && "Mohsen" # name equals to false var family = true && "Alizadeh" # family equals to Alizadeh
цитата: "Что означает конструкция x = x || y?"
присвоение значения по умолчанию.
Это значит предоставление значения по умолчанию от y до x, в случае, если x все еще ждет своего значения, но еще не получил его или был намеренно опущен, чтобы вернуться к умолчанию.
и я должен добавить еще одну вещь: эта стенография-это мерзость. Он неправильно использует случайную оптимизацию интерпретатора (не беспокоясь о второй операции, если первая истинна) для управления назначением. Это использование не имеет ничего общего с целью оператора. Я не верю, что он когда-либо должен быть использован.
Я предпочитаю тернарный оператор для инициализации, например,
var title = title?title:'Error';
это использует однострочную условную операцию для ее правильного назначения. Оно все еще играет неприглядные игры с правдивостью, но это Javascript для вас.