JavaScript・Python・Swiftでは配列の挙動が違いハマった話

# 背景：　自分は初心者なんだと改めて・・・
- ２年もPythonとかSwiftとか使うエンジニアをやっていて、「参照型」や「値型」を理解していなかったことに反省
- 未来の自分が、こんなしょうもないことでショックを受けていたのかと見返すための記事

- 以下は、今回のバージョン情報
    ||バージョン|
    |--|--|
    |macOS|13.3.1|
    |JavaScript|Node.js18.12.1|
    |Python|3.9.6|
    |Swift|5.8|


# 実験と結果：　　言語ごとに違う配列定義の挙動

- **実験1**：　
    - JavaScript・Python・Swiftで同じ要素を持つ配列を比較したらその結果は`true`か？
- **結果1**：　
    - JavaScriptだけ`false`

    ```bash:サンプルと結果
    # 同じ内容の配列を定義
    変数A = 配列[１、２、３、４]
    変数B = 配列[１、２、３、４]
    # この結果はture？？
    ログ出力（変数A == 変数B）
    ## -> 結果
    ## JavaScript -> false
    ## Python  -> True
    ## Swift   -> true
    ```

    <details>
    <summary>※エビデンス（ターミナルのスクショ）</summary>
    
    <hr>
    
    ### JavaScript
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/1a25eb69-eb49-ff98-3518-c47a431ecf88.png" width=300>
    
    ### Python
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/d0ab985a-6de0-c927-b2d2-ea80e94a9ee6.png" width=300>
    
    ### Swift
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/819b8b8c-168d-6ef4-7e73-e3dd42f70be8.png" width=300>
    
    <hr>
    
    </details>

- **実験2**：　
    - JavaScript・Python・Swiftで配列を定義した後、別の変数に渡して、それに要素を追加したら、最初に定義した方は元のまま？
- **結果2**：　
    - Swiftだけ`[1, 2, 3]`のまま

    ```bash:サンプルと結果
    # 配列を変数Aに定義した後、別の変数Bに渡す
    変数A = 配列[１、２、３]
    変数B = 変数A
    # 変数Bに要素を追加
    変数B.要素追加（4）
    # この時の変数Aは[１、２、３]のままか？  
    ログ出力（変数A）
    ## -> 結果
    ## JavaScript -> [1, 2, 3, 4]
    ## Python  -> [1, 2, 3, 4]
    ## Swift   -> [1, 2, 3]
    ```

    <details>
    <summary>※エビデンス（ターミナルのスクショ）</summary>
    
    <hr>
    
    ### JavaScript
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/31e8b3a0-3c7b-68d4-9d30-09d97d2f8a12.png" width=400>
        
    ### Python
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/6c5b7064-9218-1294-af2e-7aa6c32a4290.png" width=400>
        
    ### Swift
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/9585200c-52af-9a3e-1ef4-e77e372ca9fa.png" width=400>
    
    <hr>
    
    </details>

・・・どういうことだ、、、、と思い、調べた結果が続きです

# 結論と考察：　

### 参考サイト
- https://www.zoma-blog.com/post/frontend/js/js_array_comparison/
- https://tech.anti-pattern.co.jp/javascriptde/
- https://qiita.com/koher/items/2a1a364de98845ac6963

### 実験結果と調べた結果のまとめ
- 配列の定義の仕方には「参照型（Reference Type)」と「値型（Value Type）」なるものがあるらしい
- それと実験結果を対応させた表が以下の通り
    ||JavaScript|Python|Swift|
    |--|--|--|--|
    |**配列の型**|参照型|参照型|値型|
    |**実験1結果**|false|True|true|
    |**実験2結果**|[1, 2, 3, 4]|[1, 2, 3, 4]|[1, 2, 3]|

- なるほど！だから**実験1**では、JavaScriptは定義した変数それぞれの配列のメモリ位置が違うから`false`になるし、Swiftは値を見てるからコピーされていて`true`になるわけか　**←わかる**
- そして、**実験2**では、JavaScriptとPythonは参照渡ししてるから元の配列の要素も変わるし、Swiftは値渡しだから元の定義はさすがに変わらんか　**←わかる**
- Pythonの配列は「参照型」でメモリ位置が違うはずなのに**実験１**が`True`　**←？？**

→~~どうやら、Pythonの配列は「参照型」なのだけど、比較の時にはちゃんと配列の要素と順番を持ってきてくれるらしい（知らんけど）~~

- →※記事にコメントいただきましたので加筆修正。Pythonの配列は「参照型」で間違いないが、`==`で比較すると値が同値かを判断し、`is`で比較すると、メモリ位置である`id`が同値かを判断してくれるらしいです（下記の画像とリンク参照）。
    - https://www.python-izm.com/tips/difference_eq_is/
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918864/efbb2a88-d138-8aab-9c73-755d1749cd22.png" width=300>

### 最終的にわかったことまとめ
1. JavaScriptの配列は参照型であり、比較演算子を使うときはメモリ位置を参照する
1. Pythonの配列も参照型ではあるが、~~比較演算子を使う時は配列の要素と順番を見てくれる~~ 比較演算子`==`を使う時は配列の要素と順番を見てくれる。`is`を使うと、メモリ位置を参照する。
1. Swiftはそもそも配列が値型




以上です。