JavaScript学習で苦戦した演習問題まとめ

# はじめに

JavaScriptの学習中に取り組んだ演習問題で
苦戦した内容をまとめたいと思います。

# 目次
1. thisを使った演習問題
2. filterメソッドを使った演習問題
3. everyメソッドを使った演習問題
4. 自分がよくやるミス
5. まとめ


## 1.thisを使った問題
>thisは<strong>同じオブジェクト内の、他のプロパティを使いたいとき</strong>に活用します。
thisの値は、thisを使っている関数が<strong>どのように呼ばれたか</strong>に依存します。

---------------------------------------
問題
dogというオブジェクトを定義し、2つのプロパティと、1つのメソッドを定義してください。

* nameは'Pochi'にしてください
* toyCountは0にしてください
* getAtoyというメソッドを定義してください
  このメソッドは、自分のtoyCountを1加算して、'TOY'という文字列をreturnしてください。（thisを使う必要があります）
---------------------------------------  
getAtoyメソッドが処理されるたびに、toyCountに1が加算されるので、toyCountはgetAtoyが処理された回数を表示します。
以下が最初に回答した不正解の内容です。
```php
//不正解
const dog = {
    name: 'Pochi',
    toyCount: 0,
    getAtoy() {
        toyCount = this.toyCount + 1;
        return 'TOY';
    }
}

dog.name // "Pochi"
dog.toyCount // 0
dog.getAtoy() // "TOY"
dog.getAtoy() // "TOY"
dog.toyCount // 0
```
dog.getAtoy()を2回呼び出し、1が2回加算されたはずのtoyCountが0のままでした。
これは、1が加算されたthis.toyCountの代入先がthisを付け忘れたtoyCountだったことが原因でした。
thisを付ける場所を間違えているのかと何度も書き直しましたが、代入先のtoyCountにもthisが必要だったことには全く気付いていませんでした。


修正を繰り返して辿り着いた正しい答えは、以下の通りです。
```php
//正解
const dog = {
    name: 'Pochi',
    toyCount: 0,
    getAtoy() {
        this.toyCount = this.toyCount + 1;
        return 'TOY';
    }
}

dog.name // "Pochi"
dog.toyCount // 0
dog.getAtoy() // "TOY"
dog.getAtoy() // "TOY"
dog.toyCount // 2
```
ほとんど違いはありませんが、getAtoyのtoyCountにthisが付けられています。
この場合のthisはdogを指しているので、thisを付けることで関数dogのtoyCountに1ずつ加算され、dog.toyCountが2になりました。

## 2.filterメソッドを使った問題
>filterは<strong>提供されたテスト関数を満たす要素からなる新しい配列を生成</strong>します。

---------------------------------------
問題
validAnimalNamesという関数を作ってください。
この関数はStringの配列を引数として受け取って、Stringの長さが5文字未満の値だけが入っている新しい配列を返してください。

```php
//実行例
validAnimalNames(['dog', 'cat', 'rabbit', 'horse', 'kangaroo', 'bear']);
// => ["dog", "cat", "bear"]
// 'rabbit', 'horse', 'kangaroo'は5文字以上なので返ってきた配列には含まれない
```

---------------------------------------
filterやsome,everyの演習問題も難易度が高いものではなかったのですが、
関数とメソッドの理解がごちゃ混ぜな状態でアロー関数について学び、filterやsome,everyの内容へ進んでしまったため、書き方がめちゃくちゃになってしまいました。
不正解を見て、どこが理解できていなかったかを振り返りたいと思います。

```php
//不正解
validAnimalNames.filter(validAnimalNames => {
    return validAnimalName.length < 5;
});
```
関数を作ることと、filterメソッドを使うことを同時に行おうとしたために、書き方がおかしくなってしまったと思います。
そのため、まず関数を作りその中にfilterメソッドを書くという順番で基本的な書き方を覚えられるよう意識しました。

```php
//正解
function validAnimalNames(Array) {
    const filteredArray = Array.filter(name => name.length < 5 ) 
    return filteredArray
}

// => ["dog", "cat", "bear"]
```

## 3.everyメソッドを使った問題

>everyは<strong>排列内のすべての要素が指定されたテスト関数を満たすかどうかをtrueかfalseで返します。</strong>

---------------------------------------
問題
evenNumsという関数を定義してください。この関数は配列を一つ引数として受け取って、その配列の中身がすべて偶数であればtrueを返してください。そうでない場合はfalseを返してください。everyメソッドを使用してください。

```php
//実行例
evenNums([2,6,12,18]) //true（すべて偶数）
evenNums([3,4,16,22]) //false（奇数が含まれている）
```
---------------------------------------

everyメソッドの問題もfilterメソッドの問題と同じように、evenNums関数の定義とeveryメソッドの使用を同時に行おうとしたことで正しく書くことができていませんでした。

```php
//不正解
allEvens.every(allEven => {
    return allEven % 2 === 0;
})
```

filterメソッドと同様に、evenNums関数を作りその中にeveryメソッドで条件を書くという順番を意識したことで、正しい型を理解して書くことができました。

```php
//正解
function evenNums(Array) {
    const resultEvent = Array.every(num => num % 2 === 0)
        return resultEvent
}

evenNums([2,6,12,18]) //true
evenNums([3,4,16,22]) //false
```

## 4.自分がよくやるミス
自分が演習問題で苦戦する時の原因は「書き方を理解していない」ことの他に、「誤字に気付いていない」ことも多いです。
書き方は正しいのに1字の誤字に気付かず何度も書き直して時間を掛けてしまう場面が、これまでにも多々ありました。
そのため、演習問題だけでなく実際にコードを書く場面でエラーが出た際には、まず誤字を疑うことを意識したいと思います。

## 5.まとめ
演習問題を解くことで、自分がどこを理解していてどこを理解していないのかを明確にすることができました。
演習問題の内容を振り返ることや再度解きなおすことで、より身に付いていくと考えられるので、時間を空けて改めて上記の問題を解いてみたいと思います。


### 参考資料
[Udemy【世界で70万人が受講】Web Developer Bootcamp 2023（日本語版）](https://www.udemy.com/course/the-web-developer-bootcamp-2021-japan/?couponCode=ST2MT43024　"Udemy")　※1

※1 本記事ではUdemyの演習問題を参考に類似した問題を作成し、記載しています。