久しぶりにJavaScriptを触る未来の私へ

JavaScriptを学び中の今、混乱したこと・違和感を感じたことのリスト。
きっと数ヶ月・数年経って久しぶりにJavaScriptを使う私が同じところで躓くと思うので、ここに残します。

# VSCodeでJavaScriptでデバッグする

参考：[Visual Studio CodeでのJavaScriptのデバッグ方法](https://iyo-shimizuya.com/wordpress/2024/09/18/%E3%80%90%E3%80%91visual-studio-code%E3%81%A7%E3%81%AEjavascript%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%96%B9%E6%B3%95/)

```text:ファイル構成
model\
 `javascript01\
  |`sample.html
   `main.js
```

```html:sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script defer src="main.js"></script>
  </head>
  <body>
    <div class="container">
      <button id="go">GO!</button>
    </div>
  </body>
</html>
```

```js:main.js
'use strict';

const goButton = document.querySelector("#go");

goButton.addEventListener("click", kansu);

function kansu() {
  // ここに処理を書く
}
```

JavaScriptは別にWebサイト・Webブラウザ上だけで動くわけじゃないんだけど
今回の学習の内容からしてもこんな実装したうえで動かすのがよさげ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/8ddb2477-95c5-c6a3-fc88-a5533c125306.png)

Live Previewでhtmlを表示してWebサーバ立ててURLをコピペしておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/25585c57-e4c2-38a6-3670-59a198b22a0c.png)

初めてデバッグさんボタンを押すとこんなメッセージが出るので`launch.jsonファイルを作成します`を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/62b15b18-ffa8-41b3-82dd-7bc3139154c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/1b22ad59-4648-372b-4720-9a7934335656.png)

当然最後は`Chrome`でもいいんだけど今現在の私はEdge派。

```text:ファイル構成
model\
|`.vscode\
|  `launch.js ★
 `javascript01\
  |`sample.html
   `main.js
```

```js:launch.js
{
  // IntelliSense を使用して利用可能な属性を学べます。
  // 既存の属性の説明をホバーして表示します。
  // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "msedge",
      "request": "launch",
      "name": "Open sample.html",
      "file": "{フォルダ格納しているパス}\\model\\javascript01\\sample.html"
    }
  ]
}
```

この`launch.js`とかもなんなのかまだわかってない。12月末までにわかっているといいな。
んであとはいい感じにブレイクポイント貼っていい感じに実行すればいい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/36cccb43-6c4a-e8c7-6832-83bfe9093436.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/5c30513d-c8ee-8a54-ba84-6a737e5d7f82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/aceb1e60-033d-b7cd-20b1-91d84800bd91.png)


# 配列の定数、再定義はできないけど値の更新はできる

なんでやねん！

```js:sample.js
function kansu() {
  const fruits = ["apple", "banana", "orange"];

  fruits = ["one", "two", "three"];
}
```

```text:console.log
Uncaught TypeError TypeError: Assignment to constant variable.
    at kansu (xxxxx\model\javascript01\main.js:10:10)
```

いっぽうで

```js:sample.js
function kansu() {
  const fruits = ["apple", "banana", "orange"];

  fruits[0] = "lemon";

  console.log(fruits);
}
```

```text:console.log
(3) ['lemon', 'banana', 'orange']
main.js:12
0 = 'lemon'
1 = 'banana'
2 = 'orange'
length = 3
[[Prototype]] = Array(0)
[[Prototype]] = Object
```

なぜなの！納得いかん。が、そういうものだと現状は理解。

ちなみに`push`もできる。まじかよ。

```js:sample.js
const fruits = ["apple", "banana", "orange"];
fruits.push("grape");
```


# lengthは「要素数」。最後の要素の番号じゃない

```js:sample.js
for(let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}
```

これはNG

```js
i <= fruits.length
```

Perlあたりであったんだよな。最後の要素番号取るやつ。`$#ARGV`だっけ。
参考：[perlにおける配列要素数の取得](https://qiita.com/hatt0519/items/198af8866ac5a424be03)

コイツのせいでよくミスる。私だけじゃないはず。

# forの条件式で定義した変数はループ後に解放される

```js:sample.js
function kansu() {
  const fruits = ["apple", "banana", "orange"];

  for(let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
    console.log(i);
  }
  console.log(i);
}
```

```text:console.log
apple
main.js:11
0
main.js:12
banana
main.js:11
1
main.js:12
orange
main.js:11
2
main.js:12
Uncaught ReferenceError ReferenceError: i is not defined
    at kansu (xxxxx\model\javascript01\main.js:14:15)
```

# オブジェクトという存在

あ、ちなみに自分、言語系の習熟ほぼ皆無です。肌でbashスクリプトとperlを身に着けている程度。
で、Java系やってるとよく聞く`Map`という存在。おそらくPerlでいうところの`Hash`なんだろうけど、Progateだと「オブジェクト」っていう名前で紹介された。違うものなの？

参考：[【JavaScript】これからはオブジェクトよりも Map オブジェクトを使おう！](https://zenn.dev/torakm/articles/48f60764434537)

あ、違うものなのね。積み本。

# 配列の中のオブジェクトの呼び出し方

なんだか「Perlで育ってきた人がJavaScriptを触るときに気をつけること」になってきたな。ニッチな需要だ。

```js:sample.js
const fruits = [
{name: "orange", color: "orange"},
{name: "apple", color: "red"}
];

console.log(fruits[1].name);
```

これがPerlだと`$fruits[1]{name}`みたいな、だっけ？そんなんになるわけだ。すっごいわかりやすいね。

オマケにオブジェクトの中のオブジェクトも同じ。

```js:sample.js
const user = {
  name: "Ki2neudon",
  favorite : {
    food: "soba",
    sport: "ランニング",
    game: "ビタミーナ王国"
  }
}
console.log(user.favorite.game);
```

めっちゃ直感的～！

# アロー関数

JavaScript ES6 から導入されたらしい

```js:sample.js
const hoge = function() {
  //
}
```

を

```js:sample.js
const hoge = () => {
  //
}
```

って書ける…え、これ見やすい？でも覚えていないと「なぁにこれぇ」ってなりそう。

# forとforEachの違い

いろいろあるんだろうけど、いったんいまの理解

```js:sample.js
const fruits = ["orange", "apple", "lemon"];
for(let i = 0; i < fruits.length; i++){
  console.log(fruits[i]);
}
```

```js:sample.js
const fruits = ["orange", "apple", "lemon"];
fruits.forEach((fruit) => {
  console.log(fruit);
})
```

いちいち`i`を定義しなくていい。あと`forEach`が関数ではなくて配列のメソッド、というところ。
今回体系的にゼロから学ばないとココもぼんやり認識している程度だったんだろうなぁ