Что означает конструкция x = x || значит?
Я отлаживаю некоторый JavaScript, и не могу объяснить, что это ||
делает?
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
Может кто-нибудь дать мне подсказку, почему этот парень использует var title = title || 'ERROR'
? Я иногда вижу это без var
декларация также.
13 ответов
Это означает 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 делает неявный разговор булевыми. Это означает, что если значение является ложным (например, 0
, ""
, null
, undefined
(см. также все значения Falsey в 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
был ложным, 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). Если вы хотите поддерживать эти браузеры, вы должны перенести свой код с Babel.
Смотрите также Логические операторы на MDN.
Если заголовок не установлен, используйте "ОШИБКА" в качестве значения по умолчанию.
Более общий:
var foobar = foo || default;
Читает: Установите Foobar в foo
или же default
, Вы могли бы даже связать это много раз:
var foobar = foo || bar || something || 42;
Объясняя это немного больше...
||
Оператор является логическимor
оператор. Результат равен true, если первая часть верна, и равен true, если вторая часть верна, и он равен true, если обе части верны. Для наглядности вот оно в таблице:
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
Затем оператор оценивает второе выражение и возвращает вместо него "Ошибка". Так что теперь локальной переменной присваивается значение "Ошибка".
Это работает из-за реализации логических выражений в JavaScript. Не возвращает правильное логическое значение (true
или же false
) но вместо этого возвращает значение, которое было дано по некоторым правилам относительно того, что считается эквивалентным true
и что считается эквивалентным false
, Посмотрите свою ссылку на JavaScript, чтобы узнать, что JavaScript считает истинным или ложным в логических контекстах.
|| является логическим оператором ИЛИ. Как и в javascript, значения undefined, null, 0, false считаются ложными.
Это просто означает
true || true = true
false || true = true
true || false = true
false || false = false
undefined || "value" = "value"
"value" || undefined = "value"
null || "value" = "value"
"value" || null = "value"
0 || "value" = "value"
"value" || 0 = "value"
false || "value" = "value"
"value" || false = "value"
В основном это проверяет, если значение перед || оценивается как true, если да, он принимает это значение, если нет, он принимает значение после ||.
Значения, для которых он будет принимать значение после || (насколько я помню):
- не определено
- ложный
- 0
- '' (Нулевая или Нулевая строка)
Хотя ответ Cletus верен, я чувствую, что нужно добавить больше подробностей в отношении "оценивается как ложное" в JavaScript.
var title = title || 'Error';
var msg = msg || 'Error on Request';
Это не просто проверка наличия заголовка / сообщения, но также и фальсификации любого из них. то есть одно из следующего:
- ложный.
- 0 (ноль)
- "" (пустой строки)
- ноль.
- не определено.
- NaN (специальное числовое значение, означающее не число!)
Так в линии
var title = title || 'Error';
Если title является правдивым (т. Е. Не ложным, поэтому title = "titleMessage" и т. Д.), То логический оператор OR (||) нашел одно значение 'true', что означает, что он оценивается как true, поэтому он замыкает накоротко и возвращает истинное значение (название).
Если title является ложным (то есть одним из списка выше), то логический оператор OR (||) нашел значение "false" и теперь должен оценить другую часть оператора "Error", которая оценивается как true и, следовательно, возвращается.
Также может показаться (после некоторых быстрых экспериментов с консолью firebug), что обе стороны оператора оценивают как false, он возвращает второй оператор 'ложь'.
т.е.
return ("" || undefined)
возвращает значение undefined, возможно, это позволяет вам использовать поведение, о котором идет речь в этом вопросе, при попытке установить заголовок / сообщение по умолчанию в "". т.е. после бега
var foo = undefined
foo = foo || ""
foo будет установлен на ""
Двойная труба обозначает логическое "ИЛИ". Это не совсем тот случай, когда "параметр не установлен", так как строго в javascript, если у вас есть такой код:
function foo(par) {
}
Потом звонки
foo()
foo("")
foo(null)
foo(undefined)
foo(0)
не эквивалентны.
Двойная труба (||) приведёт первый аргумент к логическому значению, и, если полученное логическое значение истинно, выполните присваивание, в противном случае он назначит правильную часть.
Это имеет значение, если вы проверите для неустановленного параметра.
Допустим, у нас есть функция setSalary, у которой есть один необязательный параметр. Если пользователь не предоставляет параметр, то следует использовать значение по умолчанию 10.
если вы делаете проверку, как это:
function setSalary(dollars) {
salary = dollars || 10
}
Это даст неожиданный результат по вызову, как
setSalary(0)
Это все еще установит 10, следуя описанному выше потоку.
Оператор двойной трубы
этот пример полезен?
var section = document.getElementById('special');
if(!section){
section = document.getElementById('main');
}
так же может быть
var section = document.getElementById('special') || document.getElementById('main');
Чтобы добавить некоторые объяснения ко всему сказанному до меня, приведу несколько примеров для понимания логических понятий.
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 для вас.