Как работает логическое назначение javascript? - PullRequest
13 голосов
/ 15 декабря 2010

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

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

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

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

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

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

Ответы [ 6 ]

24 голосов
/ 15 декабря 2010

Чтобы ваш 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';

7 голосов
/ 15 декабря 2010

Способ работы || в Javascript:

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

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

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

var foo = (obj && obj.property)

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

1 голос
/ 15 декабря 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();
1 голос
/ 15 декабря 2010

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

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

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

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

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

1 голос
/ 15 декабря 2010

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

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

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

    // no need to test fooValue -- it's guaranteed to be defined at this point
}
0 голосов
/ 13 сентября 2011

ИМХО - не использовать для присваивания логических типов.Это может сбить с толку.Не определено! == 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;
...