Javascript И оператор в присваивании - PullRequest
54 голосов
/ 02 июля 2010

Я знаю, что в JavaScript вы можете сделать:

var oneOrTheOther = someOtherVar || "these are not the droids you are looking for...";

где переменная oneOrTheOther примет значение первого выражения, если оно не null, undefined или false. В этом случае ему присваивается значение второго оператора.

Однако, что присваивается переменной oneOrTheOther, когда мы используем логический оператор AND?

var oneOrTheOther = someOtherVar && "some string";

Что бы произошло, если someOtherVar не ложно?
Что будет, если someOtherVar ложно?

Просто изучаю JavaScript, и мне любопытно, что произойдет с присваиванием в сочетании с оператором AND.

Ответы [ 6 ]

73 голосов
/ 02 июля 2010

По сути, оператор логического И (&&) вернет значение второго операнда, если первый - truey , и вернет значение первого операнда, если он сам по себе falsy , например:

true && "foo"; // "foo"
NaN && "anything"; // NaN
0 && "anything";   // 0

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

23 голосов
/ 02 июля 2010

&& иногда называют охранником оператором.

variable = indicator && value

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

18 голосов
/ 02 июля 2010

Цитирование Дуглас Крокфорд 1 :

Оператор && создает значение своего первого операнда, если первый операнд ложный. В противном случае он выдает значение второго операнда.


1 Дуглас Крокфорд: JavaScript: Хорошие части - Страница 16

12 голосов
/ 11 августа 2014

Пример для начинающих

Если вы пытаетесь получить доступ к «user.name», но тогда это происходит:

Uncaught TypeError: Cannot read property 'name' of undefined 

Не бойся. Вы можете решить эту проблему, используя оператор && в назначении или часто называемый защитный оператор , поскольку он "защищает" от возникновения неопределенной ошибки.

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

var user = undefined;
var username = user && user.username;
// no error, "username" assigned value of "user" which is undefined

user = { username: 'Johnny' };
username = user && user.username;
// no error, "username" assigned 'Johnny'

user = { };
username = user && user.username;
// no error, "username" assigned value of "username" which is undefined

Пояснение : В операции охраны каждый член оценивается слева направо по одному . Если оцененное значение является ложным, оценка останавливается, и это значение затем присваивается. Если достигнут последний элемент, ему присваивается, является ли он ложным.

ложь означает, что это любое из этих значений undefined, false, 0, null, NaN, '' и истина просто означает НЕ ложь.

Простая кнопка для метода охраны

Используйте прекрасный оператор lodash для доступа к вложенным данным, например:

// need to access obj.has.some.very.nested.stuff
var val = _.get(obj, 'has.some.very.nested.stuff');

, так как он обрабатывает содержимое && под капотом, и в то же время удобно использовать удобным способом. Lodash _.get исходный код

Бонус: оператор ИЛИ

Другое полезное странное назначение, которое используется на практике, - это оператор ИЛИ , который обычно используется для таких плагинов, как:

this.myWidget = this.myWidget || (function() {
   // define widget
})();

, который присваивает часть кода, только если this.myWidget ложный. Это удобно, потому что вы можете объявить код где угодно и несколько раз, не заботясь о том, был ли он назначен или нет ранее, зная, что он будет назначен только один раз, так как люди, использующие плагин, могут случайно объявить ваш тег script src несколько раз.

Пояснение : Каждое значение оценивается от слева направо, по одному за раз . Если значение истинно, оно останавливает оценку и присваивает это значение, в противном случае продолжает работать, если достигнут последний элемент, оно назначается независимо от того, ложно оно или нет.

Дополнительные кредиты: Объединение && и || в назначении

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

function palindrome(s,i) {
 return (i >= s.length/2) || (s[i] === s[s.length -1 - i]) && palindrome(s, ++i);
}

Подробное объяснение здесь: Проверка палиндрома в Javascript

Удачного кодирования.

1 голос
/ 11 августа 2014

Согласно Аннотированный ECMAScript 5.1 раздел 11.11 :

В случае оператора логического ИЛИ (||),

expr1 ||expr2 Возвращает expr1, если его можно преобразовать в true;в противном случае возвращает expr2.Таким образом, при использовании с логическими значениями, ||возвращает true, если любой из операндов равен true;если оба имеют значение false, возвращает false.

В данном примере

var oneOrTheOther = someOtherVar ||«это не те дроиды, которых вы ищете ... двигайтесь вперед»;

Результатом будет значение someOtherVar, если Boolean (someOtherVar) имеет значение true . (Пожалуйста, обратитесь. Правдивость выражения ).Если значение равно false, результатом будет «это не те дроиды, которых вы ищете ... двигаться вперед»;

И в случае логического оператора AND (&&),

Возвращает expr1, если его можно преобразовать в false;в противном случае возвращает expr2.Таким образом, при использовании с логическими значениями && возвращает true, если оба операнда имеют значение true;в противном случае возвращает false.

В данном примере

case 1: когда Boolean (someOtherVar) имеет значение false: возвращает значение someOtherVar.

case2: когда Boolean (someOtherVar) имеет значение true: он возвращает «это не те дроиды, которых вы ищете ... двигайтесь вперед».

0 голосов
/ 04 апреля 2017

Я видел, как && используется здесь на работе для операторов присваивания.Проблема состоит из двух частей: 1) Проверка «индикатора» иногда является функцией с накладными расходами, которую разработчики не учитывают.2) Разработчикам легко увидеть это как проверку безопасности и не учитывать, что они присваивают false своим var.Мне нравится, чтобы у них было безопасное отношение, поэтому я могу изменить это:

var currentIndex = App.instance && App.instance.rightSideView.getFocusItemIndex();

на это:

var currentIndex = App.instance && App.instance.rightSideView.getFocusItemIndex() || 0;

поэтому они получают целое число, как и ожидалось.

...