JavaScript или ( | | ) объяснение назначения переменных

учитывая этот фрагмент JavaScript...

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

может кто-нибудь, пожалуйста, объясните мне, что эта техника называется (мое лучшее предположение находится в названии этого вопроса!)? И как/почему это работает именно?

мое понимание-это переменная f будет назначен ближайший значением (слева направо) первой переменной, которая имеет значение, не null или undefined, но мне не удалось найти много справочного материала об этой технике и видел его много раз.

кроме того, этот метод специфичен для JavaScript? Я знаю, что делать что-то подобное в PHP приведет к f имея истинное логическое значение, а не значение .

12 ответов


посмотреть оценка короткого замыкания для объяснения. Это распространенный способ реализации этих операторов; он не уникален для JavaScript.


это сделано, чтобы назначить значение по умолчанию в этом случае значение y, если x переменная ложь.

логические операторы в JavaScript возвращает операнд, и не всегда логический результат, как и в других языках.

логический оператор OR (||) возвращает значение своего второго операнда, если первый является ложным, в противном случае возвращается значение первого операнда.

для пример:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

ложь значения-это те, кто принуждает false при использовании в булевом контексте, и они 0, null, undefined, пустую строку NaN и конечно false.


Javacript использует оценка короткого замыкания для логических операторов || и &&. однако он отличается от других языков тем, что возвращает результат последнего значения, которое остановило выполнение, а не true или false значение.

следующие значения считаются ложными в JavaScript.

  • false
  • null
  • "" (пусто string)
  • 0
  • Нэн
  • неопределено

игнорировать приоритет операторов правила и сохраняя вещи простыми, следующие примеры показывают, какое значение остановило оценку и возвращается в результате.

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

первые 5 значений до NaN являются ложными, поэтому все они оцениваются слева направо, пока не встретится первое истинное значение -"Hello" что делает все выражение истинным, поэтому ничего дальше не будет оцениваться, и "Hello" возвращается как результат выражения. Аналогично в этом случае:

1 && [] && {} && true && "World" && null && 2010 // null

первые 5 значений являются истинными и оцениваются до тех пор, пока не встретится первое ложное значение (null), что делает выражение ложно, так 2010 больше не оценивается, и null возвращается как результат выражения.

приведенный вами пример использует это свойство JavaScript для выполнения назначение. Его можно использовать в любом месте, где вам нужно получить первое истинное или ложное значение среди набора значений. Этот код ниже присвоит значение "Hello" to b поскольку это упрощает назначение значения по умолчанию, вместо того, чтобы делать проверки if-else.

var a = false;
var b = a || "Hello";

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

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

внутри предупреждения, мы проверяем, если messages - это ложь, и если да, то оценить и вернуть noNewMessagesText, в противном случае оцените и верните newMessagesText. Поскольку это ложно в этом примере, мы останавливаемся на noNewMessagesText и alert "Sorry, you have no new messages.".


переменные Javascript не типизированы, поэтому f может быть присвоено целочисленное значение, даже если оно было назначено через логические операторы.

F присваивается ближайшее значение, которое является не эквивалентно false. Таким образом, 0, false, null, undefined, все передаются:

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'

в этом нет никакой магии. Логические выражения типа a || b || c || d лениво оценены. Interpeter ищет значение a, он не определен, поэтому он ложен, поэтому он движется дальше, Затем он видит b который равен null, который все еще дает ложный результат, поэтому он движется дальше, Затем он видит c - та же история. Наконец он видит d и говорит: "Ха, это не null, поэтому у меня есть мой результат", и он присваивает его конечной переменной.

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


на этот вопрос уже получено несколько хороших ответов.

таким образом, этот метод использует функцию компиляции языка. То есть JavaScript" закоротит " оценку булевых операторов и вернет значение, связанное либо с первым значением ненулевой переменной, либо с тем, что содержит последняя переменная. См. объяснение Anurag тех значений, которые будут оцениваться как false.

использование этой техники не хорошо практики по нескольким причинам, однако.

  1. читаемость кода: это использование логических операторов, и если поведение того, как это компилируется, не понято, то ожидаемым результатом будет логическое значение.
  2. стабильность: это использование функции, как язык компилируется, что является несовместимым между несколькими языками, и из-за этого это то, что потенциально может быть нацелено на изменения в будущем.
  3. Документированные Особенности: Существует альтернатива, которая отвечает этой потребности и согласована на нескольких языках. Это будет тернарный оператор:

    () ? значение 1: значение 2.

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

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4

возвратить вывод первое истинное значение.

Если все false, верните последнее значение false.

пример:

  null || undefined || false || 0 || 'apple'  // Return apple

Он устанавливает новую переменную (z) или значение x если это "истинный" (ненулевой, допустимый объект / массив / функция / что бы это ни было) или y иначе. Это относительно распространенный способ предоставления значения по умолчанию в случае x не существует.

например, если у вас есть функция, которая принимает необязательный параметр обратного вызова, вы можете предоставить обратный вызов по умолчанию, который ничего не делает:

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}

это означает, что если x установлено значение z будет x, иначе если y затем установите его значение будет установлено как z ' s значение.

это то же самое как

if(x)
  z = x;
else
  z = y;

это возможно, потому что логические операторы в JavaScript не возвращают логические значения, но значение последнего элемента, необходимого для завершения операции (в предложении OR это будет первое значение, не являющееся ложным, в предложении AND это будет последнее). Если операция терпит неудачу, тогда false возвращается.


свой вызванный оператор короткого замыкания.

оценка короткого замыкания говорит, что второй аргумент выполняется или оценивается только в том случае, если первого аргумента недостаточно для определения значения выражения. когда первый аргумент функции OR (||) принимает значение true, общее значение должно быть true.

Он также может использоваться для установки значения по умолчанию для аргумента функции.`

function theSameOldFoo(name){ 
  name = name || 'Bar' ;
  console.log("My best friend's name is " + name);
}
theSameOldFoo();  // My best friend's name is Bar
theSameOldFoo('Bhaskar');  // My best friend's name is Bhaskar`

он будет оценивать X и, если X не является null, пустой строкой или 0 (логическое false), то он назначит его z. Если X равно null, пустой строке или 0 (логическое значение false), то он будет присваивать y z.

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

выведет "bob";


по словам Блог Билла Хиггинса пост; логическая идиома Javascript или идиома назначения (Feb. 2007), это поведение верно для v1.2 (по крайней мере)

Он также предлагает другое использование для него (цитируется): "легкая нормализация кросс-браузерных различий"

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;