他の言語を習得した人間が学ぶES6の文法まとめ

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている@macky4です。
今回はすでにJavaやC, Pythonといった他の言語を身に付けた私がJavaScriptを学んで他の言語と違う点、重要だと思ったことをまとめました。内容は基本的な文法ばかりなので、ぜひJavaScriptを初めて学ぶ人に参考にしていただきたいです。

# ES6 とは?
JavaScript のバージョンの一つ。
JavaScript は現在 WEB 開発で必須のインタプリタ言語。
今までのバージョン ES5 に比べて ES6 はコードを効率的に書けるようになった。

# プログラムの書き方
##変数
変数の宣言には`let`を使う。（ES5では`var`を使っていた）
変数にはいろんな型の値を入れることができる。`typeof`演算子を使うとデータ型を調べられる。
定数は`let`ではなく、`const`を使う。宣言時に必ず値を代入する必要がある。
`var`は関数スコープで`let`と`const`はブロックスコープであり、`var`を使う必要性がない。

## 文字列
`console.log()`で文字列を出力できる。
文字列はシングルクォーテーションかダブルクォーテーションで囲む必要がある。
`+`で文字列を連結できる。
テンプレートリテラルでも文字列を連結できる。

```javascript
const name = "abc";
console.log("私は" + "abc" + "です"); // 「+」を使った連結
console.log(`私は${name}です`); // テンプレートリテラルによる連結
```

## 比較演算子
`===`や`!==`はデータ型も含めて等しいかどうかをチェックする。

```javascript
const name = "abc";
console.log(name === "abc");
console.log(name !== "abc");
```

## 配列
`配列.length`で配列の要素数を取得できる。

```javascript
const animals = ["dog", "cat", "sheep"];

for (let i = 0; i < animals.length; i++) {
  console.log(animals[i]);
}
console.log(animals); //　配列の中身を表示
```

## オブジェクト
各要素に名前を付けた配列のようなもので、プロパティと値をもつ。
オブジェクトの値にオブジェクトや配列を入れることも可能。
オブジェクトを`const`にしてもプロパティの変更はできる。（オブジェクト自体の参照先を変えれない）

```javascript
const character = {name: "abc", age: 14};

console.log(character.name); // オブジェクトの値を表示
console.log(character); // オブジェクトを表示
```

###オブジェクトを要素にもつ配列

```javascript
const characters = [
  {name: "abc", age: 14},
  {name: "def", age: 100},
  {name: "ghi", age: 5},
];

for (let i = 0; i < characters.length; i++) {
  const character = characters[i];
  console.log(`名前は${character.name}です`);
  console.log(`${character.age}歳です`);
  // characters[i].name でも値を取り出せる
}
```

###undefined とは
存在しない配列の要素やオブジェクトのプロパティの値を取り出そうとすると`undefined`が返ってくる。
`undefined`は if 文で判定できる。

```javascript
if (characters[i].name === undefined) {
  console.log("値がありません");
}
```

###オブジェクトの値には関数を用いることもできる

```javascript
const animal = {
  name: "abc", 
  age: 3, 
  greet: () => {
    console.log("こんにちは");
  }
};
animal.greet();
```

##関数
###定義方法
定数に`function() {}`を代入して関数を定義する。
`function　関数名(){}`でも関数を定義でき、こっちの方が望ましいらしい。
`定数名()`または`関数名()`で関数を呼び出せる。
ES6 からアロー関数が導入され、より簡潔に関数を定義できる。

```javascript
// 従来の定義方法
const greet = function() {
  console.log("おはよう");
  console.log("いい天気ですね！");
};

// アロー関数
const greet = () => {
  console.log("おはよう");
  console.log("いい天気ですね！");
};

// 関数の呼び出しどちらも同じ
greet();
```

###引数
引数の渡し方には通常の渡し方以外に、デフォルト引数・Rest 引数・スプレッド演算子がある。
Rest 引数で可変長の値を扱え、スプレット演算子で配列を展開できる。

```javascript
// デフォルト引数
function greet(message = "よろしく") {
  console.log(message);
};
greet("おはよう"); // 「おはよう」と表示される
greet(); // デフォルトの「よろしく」が表示される

// Rest引数
function add(x, ...y) {
  let result = x;
  y.forEach(i => {
    result += i;
  });
  console.log(result);
}
add(1);
add(1, 2, 3, 4);

// スプレッド演算子
const array1 = [1, 2, 3];
const array2 = [4, 5];
array1.push(...array2); // [1, 2, 3, 4, 5]
```

###戻り値
- 戻り値では条件式も返せる。

```javascript
const add = (number1, number2) => {
  return number1 + number2;
};

console.log(add(10, 5));

const check = (number) => {
  return number % 5 === 0;
};

if (check(150)) {
  console.log("5の倍数です");
} else {
  console.log("5の倍数ではありません");
}
```

###分割代入

```javascript
const car = {
  fuel: 60
};

//　二つは同じ意味
const { fuel } = car;
const fuel = car.fuel;

const { fuel: myFuel } = car; // 別名の変数に代入する
const { fuel, model = "なし" } = car; // デフォルト値の設定もできる。ただし undefined の時のみ。

const array = ["a", "b", "c"];
const [one, two, three] = array; // 配列の分割代入
```

###コールバック関数
- 引数として渡される関数で、特定のタイミングでの実行が可能。

##　クラス
###クラスの基本
- ES6 からクラスが使えるようになった。
- `class クラス名{}`でクラスを定義する。
- `new クラス名()`でクラスからオブジェクト（インスタンス）を生成する。
- インスタンスを生成した直後に、コンストラクタが実行される。コンストラクタの中でインスタンスのプロパティと値を設定する。コンストラクタには関数と同様に引数を持たせられる。
- 値はオブジェクトと同様に`インスタンス.プロパティ`で取得する。
- メソッドは`メソッド名(){}`で定義でき、`インスタンス.メソッド名()`で呼び出せる。メソッド内でインスタンスの値を使いたい場合は`this.プロパティ名`とする。
- メソッド内で他のメソッドを呼び出すには`this.メソッド名()`とする。

```javascript
// クラスを定義
class Human {
  // コンストラクタ
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  // メソッド
  greet() {
    console.log("おはよう！");
  }
  
  info() {
    this.greet();
    console.log(`名前は${this.name}です`);
    console.log(`${this.age}歳です`);
  }
}
const human = new Human("Taro", 10);　// インスタンスを生成
human.info(); // メソッドの呼び出し
```

###ファイルの関連付け
- `export default クラス名`とすることで、他のファイルでそのクラスを使えるようになる。
- ファイル A で定義されたクラスをファイル B で読み込むには、ファイル B の先頭で`import クラス名 from "ファイル名"`とする。

```javascript:human.js
class Human {
  // コンストラクタ
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  // メソッド
  greet() {
    console.log("おはよう！");
  }
  
  info() {
    this.greet();
    console.log(`名前は${this.name}です`);
    console.log(`${this.age}歳です`);
  }
}
export default Human;
```

```javascript:main.js
import Human from "./human.js";

const human = new Human("Taro", 10);
human.info();
```

###継承
- クラスを定義する時に、`class 子クラス名 extends 親クラス名`とする。
- 子クラスは親クラスの機能を引き継ぐため、親クラスのメソッドを子クラスのインスタンスから利用できる。
- 子クラス独自のメソッドを追加できるが、親クラスからそのメソッドにはアクセスできない。
- 親クラスにあるメソッドと同じ名前のメソッドを子クラスで定義すると、オーバーライドが起こる。
- コンストラクタをオーバーライドする場合、`super()`を書かなければならない。


```javascript:japanese.js
import Human from "./human.js";

class Japanese {
  constructor(name, age, nationality) {
    super(name, age);
    this.nationality = nationality;
  }
  // オーバーライド
  info() {
    this.greet();
    console.log(`名前は${this.name}です`);
    console.log(`${this.age}歳です`);
    console.log(`${this.nationality}人です`);
  }
}
```

##その他
- コードの最後にセミコロンをつける。（付けなくても正常に動くことが多いが付けた方がいい）
- `use strict`と書くと、ストリクトモードになり、それ以降のコードでのエラーチェックが厳しくなる。ファイルの先頭に書くと、他のファイルにも影響が出る恐れがあるため、関数の先頭など狭い範囲で書く方が安全。
- ブラウザの仕様によって利用できない機能を利用するためには、Babel を代表とするトランスパイルかポリフィルライブラリを利用する。
    - トランスパイルは ES6 で書かれた構文をブラウザ上で動作する構文に変換するう方法。
    - ポリフィルライブラリはブラウザ上で足りていない機能を補ってくれるライブラリ。
   
#参考資料
- Progate の「JavaScript」
- CODEPREP の「JavaScript入門　ES6編」