Как работает логическое присвоение javascript?

В javascript, если у нас есть код, например

var a = "one";
var b = q || a;
alert (b);

Оператор логического ИЛИ присвоит значение a переменной b, и предупреждение будет равно «единице».

Это ограничено только заданиями или мы можем использовать его везде?

Кажется, что пустая строка обрабатывается так же, как и undefined. Это правильно?

Как это работает с переменными AND? А как насчет их комбинаций?

Каков хороший пример того, когда использовать эти идиомы, а когда нет?


person Incognito    schedule 15.12.2010    source источник
comment
См. [Объяснение присвоения переменной JavaScript OR (||)] (stackoverflow.com/questions/2100758/) и [В Javascript, что это значит, когда в объявлении переменной есть логический оператор? ] (stackoverflow.com/questions/3088098/).   -  person Matthew Flaschen    schedule 15.12.2010
comment
Не используйте это. Это глупая синтаксическая конструкция, которая не является интуитивно понятной и замедляет чтение кода многими людьми.   -  person MK.    schedule 15.12.2010
comment
@MK, не исключайте общую конструкцию только потому, что люди, которые (пока) не знают JavaScript, с ней незнакомы.   -  person Matthew Flaschen    schedule 15.12.2010
comment
@Matthew Не видел этих вопросов, я голосую за закрытие.   -  person Incognito    schedule 15.12.2010


Ответы (6)


Чтобы ваш q || a оценивался как a, значение q должно быть ложным. То, что вы сделали, называется «Оценка короткого замыкания».

Отвечая на ваши вопросы:

  1. Логические операторы (например, и - && или - ||) можно использовать и в других ситуациях. В более общем смысле в условных выражениях, таких как if. Подробнее здесь

  2. Пустая строка не рассматривается как undefined. Оба являются ложными ценностями. Есть еще несколько ложных значений. Подробнее здесь

  3. AND или && в JavaScript не является переменной. Это оператор

  4. Вы использовали довольно распространенную идиому.

    var x = val || 'default'; //is generally a replacement for

    var x = val ? val : 'default' //or

    if (val) var x = val; else var x = 'default';

person dheerosaur    schedule 15.12.2010

|| работает в Javascript следующим образом:

  1. Если левый операнд оценивается как true, вернуть левый операнд
  2. В противном случае верните правильный операнд

&& работает аналогично.

Вы можете использовать это для встроенных проверок существования, например:

var foo = (obj && obj.property)

установит foo в obj.property, если obj определено и "правдиво".

person Anon.    schedule 15.12.2010
comment
Очень хорошо объяснено !! - person eddy; 01.08.2014
comment
Если левый операнд оценивается как истина, вернуть левый операнд Нет, это неправильно. Правда, а не true. - person T.J. Crowder; 06.12.2016

Я не совсем уверен, что понимаю ваш вопрос. Вы можете использовать выражение везде, где можете использовать выражение, а логический оператор над двумя выражениями приводит к выражению.

alert(q||a);
alert(true||false);

var x=5;
var y=0;
if (y!=0 && x/y>2) { /*do something*/ }

Последний бит полезен. Как и большинство языков, Javascript сокращает И и ИЛИ. Если первая часть AND ложна, он не оценивает второй бит - экономя вам деление на 0. Если первая часть ИЛИ верна, вторая не оценивается.

Но вы можете использовать логические операторы везде, где можете использовать выражение.

person Robert    schedule 15.12.2010

Javascript оценивает логику по истинности / ложности. Такие значения, как (false, "", null, undefined, 0, -0) оцениваются как логическая ложь.

В сочетании с ленивым вычислением операции «ИЛИ» теперь оцениваются с left to right и останавливаются при обнаружении true. Поскольку в вашем примере истинность не является буквально логическим значением, возвращается значение.

В таком случае:

x = 0; y = 5; alert(y || x)/*returns 5*/;  alert(x || y)/*also returns 5*/;

это также могут быть другие объекты.

functionThatReturnsTrue() || functionThatDoesSomething();
person gianebao    schedule 15.12.2010

Такое поведение характерно и для других языков сценариев, таких как Perl. Оператор логического ИЛИ может использоваться как синтаксическое сокращение для указания значений по умолчанию из-за того, что оператор логического ИЛИ перестает оценивать свои операнды, когда встречает первое выражение, которое оценивается как истинное: «оценить первый операнд и если значение интерпретируется как не false, присвойте его. В противном случае повторите для второго операнда. "

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

function myFunction(foo, bar) {
    var fooValue = foo || "a";

    // no need to test fooValue -- it's guaranteed to be defined at this point
}
person Kim Burgaard    schedule 15.12.2010
comment
Что делать, если значение foo ложно (не ложно)? - person JVM; 27.03.2017
comment
Это приведет к fooValue == a. В логическом контексте false, null, undefined, 0, NaN и пустая строка оцениваются как false - см. developer.mozilla.org/en-US/docs/Glossary/Falsy, чтобы узнать подробности. - person Kim Burgaard; 28.03.2017
comment
Правильный. Тогда это может потерпеть неудачу в том месте, где действительно нужно false в качестве значения. - person JVM; 28.03.2017
comment
В этом случае вы можете проверить для foo == null (который оценивается как true, если foo имеет значение null или undefined) или явно для foo === undefined, чтобы позволить указать ложные значения в качестве аргументов. В частности, вопрос заключался в том, какие логические присваивания с правой частью, такой как || b делает, и это то, что я ответил выше. - person Kim Burgaard; 28.03.2017

IMHO - не используйте для присвоения логического типа. Это может сбивать с толку. Как undefined! == false, т.е. false само по себе является значением.

Например. Если вы хотите скопировать значение поля из объекта тогда и только тогда, когда это поле определено

var bar.value = false;
var foo = true;

var foo = bar.value || foo;  // ==> should be false as bar.value is defined

Для присвоения логического типа вам действительно следует использовать

var foo = (bar.value !== undefined) ? bar.value : foo;
person Joe Kuan    schedule 13.09.2011