
Посмотрите на код ниже и попробуйте угадать, что будет напечатано на экран?

```javascript
console.log(0 || 1);
```

Правильный ответ:

<pre class='hexlet-basics-output'>
  1
</pre>

Оператор **ИЛИ** работает так, что его выполнение (слева направо) прерывается и возвращается результат первого аргумента, который можно преобразовать в `true`.

Ниже пример с оператором **И**:

```javascript
console.log(0 && 1);
```

<pre class='hexlet-basics-output'>
  0
</pre>

Оператор **И** работает так, что его выполнение (слева направо) прерывается и возвращается результат первого аргумента, который можно преобразовать в `false`.

В JavaScript есть два простых правила, по которым происходят преобразования:

* `0`, `''`, `undefined`, `NaN`, `null` приводятся к `false`. Эти значения называют [falsy](https://developer.mozilla.org/ru/docs/Glossary/Falsy).
* Всё остальное приводится к `true`

Этим активно пользуются в разработке, например, для определения значения по умолчанию:

```javascript
const value = name || '';
// Примеры
234 || ''; // 234
'hexlet' || ''; // 'hexlet'
undefined || ''; // ''
```

https://replit.com/@hexlet/js-basics-logical-expressions

Если `name` примет одно из falsy-значений, константе `value` будет присвоена пустая строка. В этом случае в последующем коде мы сможем работать с `value` как со строкой.

Но здесь есть потенциальный баг. Если `name` содержит falsy-значение, а присваивание константе value значений типа `0`, `undefined`, `NaN` или `null` допустимо, то код выше начнет работать неверно:

```javascript
// Упс
false || ''; // ''
0 || ''; // ''
undefined || ''; // ''
```

В одном из уроков мы рассмотрели операторы сравнения `===` и `!==` и упомянули, что в JavaScript так же есть операторы `==` и `!=`, но их не стоит использовать. Отличия как раз заключаются в преобразовании типов:

```javascript
console.log('' === false); // => false
console.log('' == false);  // => true
```

Пустая строка и `false` — это разные значения, поэтому оператор `===` говорит «ложь! они не равны!».

Но оператор `==` преобразует типы, и с его точки зрения пустая строка и `false` равны.

Это преобразование неявное, поэтому по возможности избегайте операторов `==` и `!=`.

---

Вспомните операцию отрицания:

```javascript
const answer = true;
console.log(!answer); // => false
```

Отрицание работает внутри выражений:

```javascript
!false || ''; // true
```

Если выражение обернуть в скобки и поставить перед ними `!`, то будет отрицание всего выражения:

```javascript
// Выражение обернуто в скобки
console.log(!('' === false)); // => true
console.log(!('' == false));  // => false
```

При двойном отрицании `!!` итоговое значение равно начальному:

```javascript
const answer = true;
console.log(!!answer); // => true
```

Но здесь дополнительно может происходить преобразование типа. Поэтому результатом двойного отрицания всегда будет значение типа *boolean*. Этим приемом иногда пользуются, чтобы поменять тип данных.

## Ошибка выбора

Представьте себе задачу, в которой нам нужно проверить, что значение равно либо одному, либо другому. Например, переменная `value` должна содержать одно из двух значений: `first` или `second`. Начинающие разработчики иногда записывают это выражение так:

```javascript
value === ('first' || 'second')
```

В голове мы это себе примерно так и представляем, но языки работают по-другому, поэтому такой код приведет к неверному результату. Как его правильно прочитать? Мы должны вспомнить приоритет выполнения операций. Первым делом вычисляется все что указано в скобках, то есть `'first' || 'second'`. Если выполнить этот код в repl, то вывод будет таким:

```bash
node
'Welcome to Node.js v17.4.0.
> 'first' || 'second'
'first'
>
```

Теперь мы можем заменить исходное выражение, на частично вычисленное:

```javascript
value === 'first'
```

Совсем не то, что мы ожидали. А теперь вернемся к началу, и напишем проверку правильно:

```javascript
// Скобки ставить не обязательно,
// потому что приоритет === выше чем приоритет ||
value === 'first' || value === 'second'
```
