【JavaScript】演算子

# 概要
JavaScriptを学習、理解を深めるため「[JavaScript Primer 迷わないための入門書](https://jsprimer.net/)」を読み、
理解した内容等を記載していく。

「[【JavaScript】JavaScript入門一覧](https://qiita.com/andota05/items/22fae452225b785fd405)」に他の記事をまとめています。

# この記事で理解できること
* JavaScriptのよく使われる演算子について
* 各演算子の評価結果例

# 押さえておきたいキーワード

| 名称 | 演算子 |
|-----------|------------|
| 被演算子(オペランド) ***1**| 計算や(文字列)結合などされる対象| 
| NaN     | どの数値とも一致しない特性を持つが、Number型の値を表現しているもの|

***1** 以降「被演算子」については「オペランド」と表記する

# JavaScriptの演算子
* 使用頻度の高いと思われる各演算子について記載していく。

## 二項演算子
* ２つのオペランドを取る演算子。

| 名称 | 演算子 | 概要 |
|:-----------|:------------:|:------------|
| プラス演算子       | +        | 数値と数値を足す         |
| 文字列結合演算子     | +      | 文字列を結合(くっつける)       |
| マイナス演算子       | -        | 数値から数値を引く         |
| 乗算演算子         | *          | 数値と数値をかける           |
| 除算演算子       | /       | 割り算       |
| 剰余演算子    | %     | 2つの数値の余りを計算      |
|べき乗演算子|**|ある数値の○乗を計算|

```js
/** プラス演算子 */
console.log(1 + 1);                  // => 2

/** 文字列結合演算子 */
console.log('Hello' + 'World');      // => HelloWorld

/** マイナス演算子 */
console.log(2 - 1);                  // => 1

/** 乗算演算子 */
console.log(2 * 1);                  // => 2

/** 徐算演算子 */
console.log(6 / 2);                  // => 3

/** 剰余演算子 */
console.log(5 % 2);                  // => 1

/** べき乗演算子(ES2016〜) */
console.log(2 ** 2);                 // => 4
```

## 単項演算子
* 1つのオペランドを取る演算子。

| 名称 | 演算子 | 概要 |
|:-----------|:------------:|:------------|
| 単項プラス演算子       | +        | オペランドを数値へ変換        ||
| 単項マイナス演算子     | -      | オペランドをマイナスの数値へ変換、反転できる       | 変換できない場合は、NaNになる
| インクリメント演算子       | ++        | オペランドの数値を+1する        | 配置がオペランドの前後よって結果が異なる
| デクリメント演算子         | --          | オペランドの数値を-1する           | 配置がオペランドの前後よって結果が異なる

```js
/** 単項プラス演算子 */
console.log(+1);                     // => 1
console.log(typeof +1);              // => number
console.log(+"1");                   // => 1
console.log(typeof +"1");            // => number
// 変換できない場合は、NaNになる
console.log(+"Hello");               // => NaN
console.log(typeof +"Hello");        // => number
console.log(isNaN(+"Hello"));        // => true

/** 単項マイナス演算子 */ 
console.log(-1);                     // => -1
console.log(typeof -1);              // => number
console.log(-"1");                   // => -1
console.log(typeof -"1");            // => number
console.log(-(+1))                   // => 1
// 変換できない場合は、NaNになる
console.log(-"Hello");               // => NaN
console.log(typeof -"Hello");        // => number
console.log(isNaN(-"Hello"));        // => true

/** インクリメント演算子 */ 
let num1 = 1;
let num2 = 1;

console.log(num1++);                 // => 1 現在の値を評価(まだインクリメントされていない)
console.log(num1);                   // => 2 再評価
console.log(++num2);                 // => 2 現在の値を評価(インクリメントされている)
console.log(num2);                   // => 2 再評価

/** デクリメント演算子 */
let num3 = 1;
let num4 = 1;

console.log(num3--);                 // => 1 現在の値を評価(まだデクリメントされていない)
console.log(num3);                   // => 0 再評価
console.log(--num4);                 // => 0 現在の値を評価(デクリメントされている)
console.log(num4);                   // => 0 再評価
```

## 比較演算子
* オペランド同士を比較し、真偽値を返す。

| 名称 | 演算子 | 概要 |
|:-----------|:------------:|:------------|
| 厳密等価演算子       | ===        | 同じ型、同じ値の場合`ture`を返す        |
| 厳密不等価演算子     | !==      | 異なる型、異なる値の場合`true`を返す       | 
| 大なり演算子       | >        | 左オペランドが右オペランドより大きい場合`true`を返す        |
| 大なりイコール演算子         | >=          | 左オペランドが右オペランドより大きい、または等しい場合`true`を返す           |
| 小なり演算子 | < | 左オペランドが右オペランドより小さい場合`true`を返す |
| 小なりイコール演算子 | <= | 左オペランドが右オペランドより小さい、また等しい場合`true`を返す |

※`等価演算子(==)`、`不等価演算子(!=)`も存在するが、あえて省略(`厳密等価演算子(===)`、`厳密不等価演算子(!==)`を使用した方が良いケースが多いため)

```js
/** 厳密等価演算子 */
console.log(1 === 1);                // => true
console.log(1 === 2);                // => false
console.log(1 === "1");              // => false

// オブジェクトは参照元が同じ場合true
const objA = {};
const objB = {};
console.log(objA === objA);          // => true
console.log(objA === objB);          // => false

/** 厳密不等価演算子 */
console.log(1 !== 1);                // => false
console.log(1 !== 2);                // => true
console.log(1 !== "1");              // => true

// オブジェクトは参照元が異なる場合true
const objC = {};
const objD = {};
console.log(objA !== objA);          // => false
console.log(objA !== objB);          // => true

/** 大なり演算子 */
console.log(2 > 1);                  // => true

/** 大なりイコール演算子 */
console.log(2 >= 1);                 // => true
console.log(2 >= 2);                 // => true

/** 小なり演算子 */
console.log(1 < 2);                  // => true

/** 小なりイコール演算子 */
console.log(1 <= 2);                 // => true
console.log(2 <= 2);                 // => true
```

## 代入演算子
| 名称 | 演算子 | 概要 |
|:-----------|:------------:|:------------|
| 代入演算子       | =        | 変数に値を代入する        |

```js
/** 代入演算子 */
const name = "Taro";
console.log(name);                      // => Taro
```

## 論理演算子
| 名称 | 演算子 | 概要 |
|:-----------|:------------:|:------------|
| AND演算子       | &&        | 左辺の評価結果によって左辺もしくは右辺の評価結果が返される        |
| OR演算子       | \|\| | 左辺の評価結果によって左辺もしくは右辺の評価結果が返される         |
| NOT演算子       | !        | オペランドの評価結果を反転させた真偽値を返す        |

```js
/** AND演算子 */
// 左辺がtrueの場合、右辺の評価結果を返す
console.log(true && false);             // => false(右辺)

// 左辺がfalseの場合、左辺の評価結果を返す
console.log(false && true);             // => false(左辺)

/** OR演算子 */
// 左辺がtrueの場合、左辺の評価結果を返す
console.log(true || false);             // => true(左辺)

// 左辺がfalseの場合、右辺の評価結果を返す
console.log(false || true);             // => true(右辺)

/** NOT演算子 */
// 評価結果を反転させた真偽値を返す
console.log(!true)                      // => false
```

## 条件演算子(三項演算子)
```js
// 条件式 ? trueの場合の処理 : falseの時の処理;
const result1 = true ? "trueの場合はこちらを代入" : "falseの場合はこちらを代入";
console.log(result1);                   // => trueの場合はこちらを代入

const result2 = false ? "trueの場合はこちらを代入" : "falseの場合はこちらを代入";
console.log(result2);                   // => falseの場合はこちらを代入

// ※if文でも同じようなことができる
const num = 1;
let result;

if (num > 0) {
  result = "trueの場合はこちらを代入";
} else {
  result = "falseの場合はこちらを代入";
}

console.log(result);                    // => trueの場合はこちらを代入
```

## グループ化演算子
* `(` `)`で囲うことで演算子の優先度を高くすることができる。
```js
/** グループ化演算子 */
// 2 * 4が優先される
const result1 = 2 * 4 + 3;
console.log(result1);                   // => 11

// グループ化演算子で4 + 3の優先度を高くする
const result2 = 2 * (4 + 3);
console.log(result2);                   // => 14
```