【JavaScript】知ってると便利な機能集

# この記事について
この記事には僕が「へーこんな機能JavaScriptにあったのかー」と思った機能を紹介します。
まだ初心者なので間違ってることがあったらコメントで教えてほしいです。

中にはES6の機能があるので古いブラウザだと動作しないコードがあります。
一応Google Chromeで動作確認をしています。

# 関数
関数の知っていると便利な機能です。

## アロー関数
関数を短く書けるやつです。

```JavaScript
const Add = (x, y) => { return x + y }
console.log(Add(1000, 24)) // 1024
```

引数が1つの場合`()`を省略することができます。

```JavaScript
const Double = v => v * 2
console.log(Double(256)) // 512
```

処理の内容が`return`文だけなら`{}`と`return`を省略することができます。

```JavaScript
const Power = v => v ** 2
console.log(Power(8)) // 64
```

なおアロー関数は`this`を持っていません。
アロー関数内で`this`を使用するとアロー関数の定義されたオブジェクトを指します。

```JavaScript
const Timer = {
  time: 0,
  start() {
    setInterval(() => {
      // this は Timer オブジェクトを指す
      this.time += 1
      console.log(this.time)
    }, 1000)
  }
}

Timer.start() // 1, 2, 3, ...
```

## 分割代入を利用した引数
このようなプログラムがあるとします。

```JavaScript
const BMI = (body) => {
  // body は weight と height からなるオブジェクト
  return body.weight / (body.height ** 2)
}

console.log(BMI({ height: 1.6, weight: 50 })) // 19.53124...
```

引数の`body`は`weight`と`height`のプロパティを含むオブジェクトを想定しています。
引数に**分割代入**を利用するとスマートに書けます。分割代入を利用した引数の書き方は`{ プロパティ1, プロパティ2, ... }`のように書きます。

```JavaScript
const BMI = ({ weight, height }) => {
  // { weight, height } で weight と height に body の対応するプロパティの値が代入される
  return weight / (height ** 2)
}

console.log(BMI({ height: 1.6, weight: 50 })) // 19.53124...
```

## 即時関数
名の通り即時に実行される関数です。
スコープを作りたいときなんかに使われます。

```JavaScript
(function () {
  const message = 'Hello, world'
  console.log(message)
})()

message // Uncaught ReferenceError: message is not defined
```

`(function () { ... })`で関数を定義して`()`で定義した関数を実行します。
アロー関数でも即時関数を作ることができます。

```JavaScript
(() => {
  const message = 'Hello, world'
  console.log(message)
})()

message // Uncaught ReferenceError: message is not defined
```

## オブジェクトの関数の定義
オブジェクトに関数を定義する場合は`関数名: function (...) {...}`のように書きます。

```JavaScript
const Cat {
  name: 'Siro',
  meow: function () {
    console.log(`${this.name}: Meow`)
  }
}

Cat.meow() // Siro: Meow
```

また`関数名(...) {...}`のようにも書くことができます。

```JavaScript
const Cat {
  name: 'Siro',
  meow() {
    console.log(`${this.name}: Meow`)
  }
}

Cat.meow() // Siro: Meow
```
こっちのほうがスマートですね。

## async, await
`Promise`を処理するためのキーワードです。
非同期処理に用いられます。

```JavaScript
const Wait = ms => new Promise(r => setTimeout(r))
const Wait2Seconds = async () => await Wait(2000)

// 2秒後に Hello を表示する
await Wait2Seconds()
console.log('Hello')
```

最近は`fetch`とセットで使うことがあります。
次のコードはISBNから本のタイトルを取得する例です。

```JavaScript
const GetBook = async isbn => await fetch(`https://www.googleapis.com/books/v1/volumes?q=isbn:${isbn}`)

// fetchの戻り値の json や text などはPromiseを返すため await で取得する
const json = await (await GetBook(9784822292331)).json()
console.log(json.items[0].volumeInfo.title) // Scratchで楽しく学ぶアート&サイエンス
```


# 値
変数やオブジェクトなどの値に関する知っていると便利な機能です。

## 分割代入
分割代入を使用すると配列やオブジェクトから任意のプロパティを取り出して個々の変数に代入することができます。

### 配列の分割代入
配列の分割代入は`[index1, index2, ...] = [value1, value2, ...]`のように書きます。

```JavaScript
const [ x, y, z ] = [100, -250, 45]
console.log(x, y, z) // 100 -250 45
```
変数からの分割代入も可能です。

```JavaScript
const vec3 = [100, -250, 45]
const [ x, y, z ] = vec2
console.log(x, y, z) // 100 -250 45
```

### オブジェクトの分割代入
オブジェクトの分割代入は`{ property1, property2, ... } = { property1: value1, property2: value2, ... }`のように書きます。

```JavaScript
const { x, y, z } = { x: 100, y: -250, z: 45 }
console.log(x, y, z) // 100 -250 45
```
変数からの分割代入も可能です。

```JavaScript
const vec3 = { x: 100, y: -250, z: 45 }
const { x, y, z } = vec3
console.log(x, y, z) // 100 -250 45
```

## let
変数の宣言の際には`var`をよく使用します。
`let`も変数の宣言の際に使用します。
`let`で宣言された変数は**再宣言**が不可能になります。

```JavaScript
// var
var variable = 100
console.log(variable) // 100
var variable = 'Hello, world' // variableの再宣言(エラーは出ない)
console.log(variable) // Hello, world

// let
let letVariable = 100
console.log(letVariable) // 100
// letVariableの再宣言
var letVariable = 200 // Uncaught SyntaxError: Identifier 'letVariable' has already been declared
```

## const
定数の宣言に使用します。
定数とは再代入と再宣言が不可能な変数です。
円周率は自然数など変わりようがない値を代入します。

```JavaScript
// 定数 PI の宣言
const PI = 3.14
console.log(PI) // 3.14

// 再代入
PI = 3 // Uncaught TypeError: Assignment to constant variable.

// 再宣言
var PI = 3 // Uncaught SyntaxError: Identifier 'PI' has already been declared
```

## class
自分で型を定義することができます。
`class`で定義されたクラスは再定義ができません。
文法は次の通りです。

```JavaScript
class クラス名 {
  constructor() {
    this.プロパティ1 = 値1
    this.プロパティ2 = 値2
    ...
  }

  get ゲッター名() {
    return 値
  }

  メソッド(...) {...}

  static メソッド(...) {...}
}
```

```JavaScript
// Vec2 クラスの定義
class Vec2 {
  // コンストラクタ
  constructor(x, y) {
    this.x = x
    this.y = y
  }

  // メソッド
  moveBy(x, y) {
    this.x += x
    this.y += y
  }

  // ゲッター
  get length() {
    const { x, y } = this
    return Math.sqrt(x ** 2 + y ** 2)
  }

  // static なメソッド
  static Zero() {
    return new Vec2(0, 0)
  }
}

let pos = new Vec2(10, 24)
console.log(pos) // Vec2 {x: 10, y: 24}

// 移動
pos.moveBy(22, 40)
console.log(pos) // Vec2 {x: 32, y: 64}

// 長さ
console.log(pos.length) // 71.55417527999327

// x: 0, y: 0 なVec2
console.log(Vec2.Zero()) // Vec2 {x: 0, y: 0}
```

また`set セッター名(value) { 処理 }`でセッターを定義することもできます。

また次のJavaScriptではプライベートなプロパティが定義できるようになるらしいです。

## オブジェクトのプロパティ
次のコードのようにオブジェクトのプロパティ名と他の変数名が同じ場合省略することが可能です。

```JavaScript
const CreateUser = (name, age) => {
  return {
    name: name,
    age: age
  }
}

console.log(CreateUser('Taro', 24))
```

```JavaScript
const CreateUser = (name, age) => {
  return {
    name, // name という名前が同じ
    age   // age という名前が同じ
  }
}
```

## テンプレート文字列
テンプレート文字列は文字列中に変数や値を埋め込むことができます。
テンプレート文字列は'や"ではなく \` で文字列を囲みます。
またテンプレート文字列の中に`${変数または値}`で値を埋め込むことができます。

```JavaScript
const Greet = name => `Hi, ${name}!`

console.log(Greet('Taro')) // Hi, Taro!
```


# まとめ
これからも追加していく予定です。
QiitaにもStackoverFlowみたいにその場でコードを実行できたらなぁ(RunKit埋め込みとか