Ответ 1
Для объяснения см. оценку короткого замыкания. Это общий способ реализации этих операторов; он не уникален для 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
будет иметь истинное булевское значение, а не значение самого d
.
Для объяснения см. оценку короткого замыкания. Это общий способ реализации этих операторов; он не уникален для JavaScript.
Это делается для назначения значения по умолчанию, в этом случае значение y
, если переменная x
является ложной.
Логические операторы в JavaScript могут возвращать операнд, а не всегда логический результат, как на других языках.
Логический оператор OR (||
) возвращает значение своего второго операнда, если первый является ложным, в противном случае возвращается значение первого операнда.
Например:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Значения Falsy - это те, которые принуждают к false
при использовании в булевом контексте, и они 0
, null
, undefined
, пустая строка, NaN
и, конечно, false
.
Javacript использует оценку короткого замыкания для логических операторов ||
и &&
. Однако он отличается от других языков тем, что возвращает результат последнего значения, которое остановило выполнение, вместо true
или false
значения.
Следующие значения считаются ложными в JavaScript.
""
(пустая строка)Игнорируя правила приоритета оператора и сохраняя простые вещи, следующие примеры показывают, какое значение остановило оценку и в результате получило результат.
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
Первые 5 значений до NaN
являются ложными, поэтому все они оцениваются слева направо, пока они не соответствуют первому истинному значению - "Hello"
что делает все выражение истинным, поэтому ничего дальше не будет оцениваться, а "Hello"
получает возвращается в результате выражения. Аналогично, в этом случае:
1 && [] && {} && true && "World" && null && 2010 // null
Первые 5 значений являются правдивыми и оцениваются до тех пор, пока они не удовлетворяют первому значению фальши (null
), которое делает выражение ложным, поэтому 2010
больше не оценивается, а null
возвращается в результате выражения.
В приведенном примере используется это свойство JavaScript для выполнения задания. Его можно использовать везде, где вам нужно получить первое значение правды или ложности среди набора значений. Этот код ниже присваивает значение "Hello"
в 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 и предупреждаем "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
, он undefined, поэтому он false, поэтому он перемещается, затем видит b
, который является null, который все еще дает ложный результат, поэтому он перемещается, а затем видит c
- тот же история. Наконец, он видит d
и говорит: "Да, это не null, поэтому у меня есть результат", и он присваивает его конечной переменной.
Этот трюк будет работать на всех динамических языках, которые выполняют ленивую оценку коротких замыканий булевых выражений. В статических языках он не будет компилироваться (ошибка типа). В языках, которые стремятся оценить булевы выражения, оно вернет логическое значение (т.е. True в этом случае).
Этот вопрос уже получил несколько хороших ответов.
Таким образом, этот метод использует преимущества того, как язык компилируется. То есть JavaScript "коротких замыканий" оценивает булевы операторы и возвращает значение, связанное либо с первым значением не-ложной переменной, либо с любой последней переменной. См. Anurag объяснение тех значений, которые будут оцениваться как false.
Использование этого метода не является хорошей практикой по нескольким причинам; однако.
Документированные функции: существует существующая альтернатива, которая отвечает этой потребностям и согласуется с другими языками. Это был бы тернарный оператор:
()? значение 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
Возвращаемый результат первое истинное значение.
Если все ложные значения возвращают последнее ложное значение.
Пример: -
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
.
это то же самое, что и
if(x)
z = x;
else
z = y;
Это возможно, потому что логические операторы в JavaScript не возвращают логические значения, а значение последнего элемента, необходимого для завершения операции (в предложении OR это будет первое недопустимое значение, в предложении AND это будет последний). Если операция завершается с ошибкой, возвращается false
.
Его называемый оператор короткого замыкания.
Обнаружение короткого замыкания говорит, что второй аргумент выполняется или оценивается только в том случае, если первый аргумент недостаточен для определения значения выражения. когда первый аргумент функции OR (||) имеет значение true, общее значение должно быть истинным.
Он также может использоваться для установки значения по умолчанию для аргумента функции.
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend name is " + name);
}
theSameOldFoo(); // My best friend name is Bar
theSameOldFoo('Bhaskar'); // My best friend name is Bhaskar`
Он будет оценивать X и, если X не является нулевым, пустая строка или 0 (логическая ложь), тогда она назначит ее z. Если X равно null, пустая строка или 0 (логическая ложь), то она назначит y в z.
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
Выведет 'bob';
Согласно сообщению блога Биг Хиггинса; логическая логика логического ИЛИ Javascript (февраль 2007 г.), это поведение истинно с v1.2 (по крайней мере)
Он также предлагает другое использование для него (цитируется): " облегченная нормализация различий между браузерами"
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
Я нашел эту ссылку оценка короткого замыкания в JS, она очень хорошо подходит к этому вопросу. Я знаю, что этот вопрос был опубликован давно.