【JavaScript】論理演算子(&&, ||)は必ず真偽値（true, false）を返すと勘違いしていた


JavaScriptの論理演算子は必ず`true`または`false`をかえすと思っていたけど勘違いしていた話です。

例えば真偽値以外のプリミティブな値で論理演算をした時に返ってくる値は下記になります。

```js
name = "yamada" && "satou"  //satou
name = "yamada" || "satou"  //yamada
```
AND演算子,OR演算子ともに文字列を返していることがわかります。
true/false以外が返ってくるのが意外だったので論理演算子の仕様を調べて見ました。

# 仕様
[mozilla論理演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators)から仕様を調べました。
大事だと思う部分を引用しますが、リンク先のドキュメントは全部読んだ方がいいと思います。

##概要
>論理演算子 (Logical operators) は、**基本的**に真偽（論理）値とともに用いられます。そのときは、真偽値を返します。しかし、&& および || 演算子は、**実際には、指定された演算対象の一方を返します。**ですから、それらの演算子が、真偽値ではない値とともに用いられた場合、真偽値ではない値を返す可能性があります。

ようするに演算対象にtrueまたはfalseが使われた時は、どちらかを返してるからtrueまたはfalseが返却されているのであって、演算対象に真偽値以外のプリミティブ値（string,numberなど）を使った場合は真偽値以外を返すらしいです。

##説明
>| 演算子                 |          使用法          | 説明                                                                                                                                                                                                                                                             |
| :--------------------- | :----------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `論理 AND(`&&`)`       |     `expr1 && expr2`     | `expr1`を `false` と見ることができる場合は、`expr1` を返します。そうでない場合は、`expr2` を返します。したがって、真偽値と共に使われた場合、 演算対象の両方が `true` ならば、`&&` は、`true` を返し、そうでなければ、`false` を返します。                        |
| 論理 OR (&#124;&#124;) | expr1 &#124;&#124; expr2 | `expr1` を `true` と見ることができる場合は、`expr1` を返します。そうでない場合は、`expr2` を返します。したがって、真偽値と共に使われた場合、 演算対象のどちらかが `true` ならば、&#124;&#124; は、`true` を返し、両方とも `false` の場合は、`false` を返します。 |

論理演算子は下記truthy/falsyに基づいて左から評価していき、上記の仕様で値を返していきます。

### truthyとfalsyについて
- [truthyとは](https://developer.mozilla.org/ja/docs/Glossary/truthy)
trueに変換できる値。（下記falsyに当てはまらないもの全てtrueと判断される）

- [falsyとは](https://developer.mozilla.org/ja/docs/Glossary/falsy)
falseに変換できる値。（false、0、""、null、undefined および NaN)）

### 論理AND(&&)の場合
AND演算子の時は左側がfalseの時はそのまま左側の値を返して、それ以外の時は右側を返します。

>``` 論理AND(&&).js
a1 = true  && true      // t && t true を返します。
a2 = true  && false     // t && f false を返します。
a3 = false && true      // f && t false を返します。
a4 = false && (3 == 4)  // f && f false を返します。
a5 = "Cat" && "Dog"     // t && t "Dog" を返します。
a6 = false && "Cat"     // f && t false を返します。
a7 = "Cat" && false     // t && f false を返します。
```

上のコードだとa3,a4,a6が`false`を返して、それ以外が右側を評価して返します。

### 論理OR（||）の場合
OR演算子は逆に左側がtrueの時にそのまま左側の値を返して、それ以外の時は右側を返します。
>```論理OR（||）.js
o1 = true  || true       // t || t true を返します。
o2 = false || true       // f || t true を返します。
o3 = true  || false      // t || f true を返します。
o4 = false || (3 == 4)   // f || f false を返します。
o5 = "Cat" || "Dog"      // t || t "Cat" を返します。
o6 = false || "Cat"      // f || t "Cat" を返します。
o7 = "Cat" || false      // t || f "Cat" を返します。
```

上のコードだとo1,o3が`true`を返してo5,o7が左側をtrueと判断して値を返し、それ以外が右側を評価して返します。

#最後に
普段何気なく使ってる物でも仕様をしっかり調べると認識と全然違うことがあるので仕様を見るのは大事だと思いました。
ドキュメントには結構サンプルも載っているので結構勉強になります。