JavaScript得意になるための道〜変数編〜

Udemyでやった内容を自分の理解に落とし込みます。ざっくり以下内容。

- **var, const, let**
- **falsyとtruthy**
- **AND条件とOR条件**
- **参照**

（Udemyの動画は[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)です、おすすめです)

# var, const, let
- **var**
◯再宣言、◯再代入
- **const**
×再宣言、×再代入
- **let**
×再宣言、◯再代入

`var`はなんでも有りなので非推奨。
変数は基本`const`で宣言して、値を書き換える必要がある(for文使ったループとか)場合は`let`で宣言するイメージです。

# falsyとtruthy

比較する際は`==`もしくは`===`を使うのですが、違いは**厳密に**比較するかしないかです。
（`==`が抽象的に、`===`が厳格に比較)
厳密に比較するかしないかでtrue,falseの結果が変わってくるという話です。

恐らくこれは実際に自分でコーディングしてconsole.log等で確認したほうが分かりやすく、イメージしやすいと思います。

例
```javascript
console.log(0 == false); // true
console.log(0 === false); // false
console.log(Boolean(0) === false) // true;
```

`===`の場合は型も考慮する必要があります。
（ちなみに私は`===`でしか実装したことありません、、)

# AND条件とOR条件
- **AND &&**
複数の条件が全て成立していたらtrue
- **OR ||**
複数の条件のうちどれか1つでも成立すればtrue

参考　[条件判定の関数ＡＮＤ（アンド）・ＯＲ（オア）・ＮＯＴ（ノット）](http://www.jimcom.co.jp/excel/function02/000130.html)

例
```javascript
<>
    {isShowFlg === true && (
        <div className={styles.productImgContent}>
            <img className={styles.mainBg} src={main_bg} alt="メイン背景" />
            <img className={styles.topLogo} src={logo} alt="ロゴ" />
            <img className={styles.mainIntroduction} src={main_title} alt="メイン紹介" />
            <img className={styles.productTitle} src={product_title} alt="商品タイトル" />
        </div>
    )}
</>
```

私はよく上記コードのようにAND条件を使っています。
`isShowFlg`を判定してtrueだったら`<div>~~</div>`の内容を表示させる、という内容です。

以下のように、true省略して見た目スッキリさせても良いです。

```javascript
<>
    {isShowFlg && (
        <div className={styles.productImgContent}>
            <img className={styles.mainBg} src={main_bg} alt="メイン背景" />
            <img className={styles.topLogo} src={logo} alt="ロゴ" />
            <img className={styles.mainIntroduction} src={main_title} alt="メイン紹介" />
            <img className={styles.productTitle} src={product_title} alt="商品タイトル" />
        </div>
    )}
</>
```

# 参照
ここからが本題です。
### 型について
- **プリミティブ型**
プログラミング言語が用意している基本的なデータ型
（`String`,`Number`,`Boolean`,`Null`などなど）
- **オブジェクト**
プリミティブ型以外全て

### プリミティブ値のコピー
```javascript
let a = "hello";
let b = a;
console.log(a); // hello
console.log(b); // hello

b = "bye";
console.log(a); // hello
console.log(b); // bye
```

3行目の`aが指しているhello`と、4行目の`bが指しているhello`は **違うメモリ場所**にそれぞれ保存されています。
そのため、5行目でbに`"bye"`を格納していますが、aは"bye"で上書きされません。

![名称未設定のノート-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/78d25809-9fab-3812-43cf-a8c4d12c76cf.jpeg)
![名称未設定のノート-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/bd44c996-3a17-014c-a5ce-daacb84f8211.jpeg)

### オブジェクトのコピー
```javascript
let c = {
    prop: 'hello'
}
let d = c;
console.log(c); // {prop: "hello"}
console.log(d); // {prop: "hello"}

d.prop = "bye";
console.log(c); // {prop: "bye"}
console.log(d); // {prop: "bye"}
```

オブジェクトの場合は、propを指す**参照元がメモリ場所に保存**されています。
そしてプリミティブ値と同じように、propを指す参照元は**違うメモリ場所にそれぞれ保存**されます。

しかし、参照先(上記コードでいう`{prop}`)は共通。。。
文字にしてみたのですが、ややこしいのでこちらも図を書いてみます。

![名称未設定のノート-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/dba418c0-acfc-0313-4971-383bc4bda21e.jpeg)

![名称未設定のノート-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/a2bfb69f-ee48-3450-f935-7dfc9de09b57.jpeg)

![名称未設定のノート-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/d029fec3-0498-25c2-5965-f724355e0db6.jpeg)

※**var, const, let**のところで、constは再代入不可と記載しましたが、オブジェクトだとアクセス可能です。
オブジェクトのコピーに記載しているコードでいうと、`let c` `let d`としていますが、`const c` `const d`としても全く同じ結果になります。

#### 複製したい場合
オブジェクトの中身はコピーしたいけど、片方だけ書き換えたい場合は、スプレッド構文を使えば複製が可能です。

```javascript
let c = {
    prop: 'hello'
}
let  d = {...c}; // スプレッド構文
console.log(c); // {prop: 'hello'}
console.log(d); // {prop: 'hello'}

d.prop = "bye";
console.log(c); // {prop: 'hello'}
console.log(d); // {prop: 'bye'}
```

#### オブジェクトの比較
```javascript
const a = {
  prop: 0,
};
const b = {
  prop: 0,
};
console.log(a === b); // false
console.log(a == b); // false
console.log(a.prop === b.prop); // true

let c = {
    prop: 'hello'
}
let  d = {...c}; // スプレッド構文
console.log(c === d); // false
console.log(c == d); // false
```

ちなみに、全く同じオブジェクトを宣言し、オブジェクトの入っている変数同士で比較しても結果はfalseになります。
![名称未設定のノート-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833388/2bf43010-eed6-d026-17d8-3ecbea1aa560.jpeg)

自分の中で曖昧なところや、引っかかりそうな部分を改めて整理してみました。

# 参考
- Udemy[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
- [条件判定の関数ＡＮＤ（アンド）・ＯＲ（オア）・ＮＯＴ（ノット）](http://www.jimcom.co.jp/excel/function02/000130.html)