2019年お世話になったJavascript（と一部Typescript）を振り返る

## はじめに
Nuxt.js+Typescriptでの開発現場に入ってはや4ヶ月。前はマークアップエンジニアだったのでせいぜいjQueryでDOM操作することしか実務ではしていませんでした。
当たり前ですが今の現場ではゴリゴリとES2015+で書くので自分の出したPRや先輩のPRを眺めながら「このメソッドとか処理よく使ったなあ」というのを振り返ります。

また、あくまでも一現場のR&D的なプロダクトの中で書いている内容なので、そのまま皆さんのプロダクトに当てはまらないということは事前にお断りさせていただきます。

では早速いってみましょう！

### アロー関数
わざわざ紹介するほどのことではないのですが、必ず使っているという意味で書きます！
もう一切functionって書かなくなりましたって話です。

```javascript
function (arg1, arg2){
  return arg1 + arg2
}
```

```javascript
(arg1, arg2) => {
  return arg1 + arg2
}
```

はい、functionはもう書かなくてOKです。厳密にいうと色々他にもあるのですが（thisの扱いとか）、簡単にかけるようになるのはいいですね。

これから下の処理ももちろんアロー関数で書いていきます。

### map
渡ってくる配列の各要素に対して処理をします。返り値は新しい配列になります。

```javascript
array1.map(処理) 

// 処理をした後のarray2が返ってくる

```
簡単なサンプルはこちら

```javascript
const array1 = [1, 2, 3, 4];

const array2 = array1.map(x => x * 2);

console.log(array2); // [2 ,4, 6, 8]

```

`map(x => x * 2)` はfunctionを使って書くと

```javascript

map(function(x) {
  return x * 2
})
```
と一緒です。

実際どんな感じで使ったりするかというと

```javascript
arrayData.map(data => {
  return new Date(data.date).toLocaleDateString()
}
```
arrayDataが渡ってきて、その中身がObjectの配列だった時に、それぞれのdata（オブジェクト）のdate（日付）を抜き出してきて新しく配列を作り出す

という感じで使ったりしました。

### reduce
配列の各要素に対して処理をします。返り値は単一の値です。（配列とは限らない）

```javascript

array.reduce(処理)

// 何かの値が返ってくる（例えば計算結果など）
```

簡単な処理はこちら

```javascript
const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1から4までを足す
console.log(array1.reduce((arg1, arg2) => {
  return arg1 + arg2
}));

// 合計値の10が返ってきます
```
実際のプロダクトでは

```javascript
array.reduce((a,b) => {
  return a + b / WEEKDAYS_COUNT // WEEKDAYS_COUNTは1週間 = 7日という意味で7としていた
})

```
みたいな感じで処理をしたりしていました。

### filter
配列に対してフィルタリングを行い、フィルタリングした後の値を新しい配列にして変更します


```javascript

const words = ['deepleaning', 'python', ' javascript', 'php', 'html', 'css'];

const result = words.filter(word => word.length >= 6);

console.log(result);
// ["deepleaning", "python", "javascript"]という配列が返ってくる
```

実際のプロダクトでは

```javascript

array.filter(array_data => {
  return array_data.program.weekday === targetWeekday
});

// array_data.weekday === targetWeekdayがtrueになるようなものだけを抽出して新しい配列を返す
```
のように使っていました。

### Object.entries
Object.entries()は、引数に与えたオブジェクトが所有する、列挙可能なプロパティの組 [key, value] からなる配列を返します。オブジェクトに対して使い、配列を返す処理をしてくれるということです。
Objectで返ってくる内容を配列で取り出したい、加工したい、という時にたまに使っていました。

```javascript

const object1 = {
  a: 'hogehoge',
  b: 10
};

console.log(Object.entries(object1));

// [["a", "hogehoge"],["b", 10]]
```

実際のプロダクトではmapと組み合わせて

```javascript

Object.entries(obj).map(([key, value]) => ({[key]: value}))

/* こんな感じのオブジェクトを

obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
}

*/

// こんな感じの返り値を出したい時に使います
/* 

[
  {
    "key1": "value1"
  },
  {
    "key2": "value2"
  },
  {
    "key3": "value3"
  }
]

*/
```

という感じで配列を作っていました。

### Object.fromEntries
Object.fromEntries()は、key valueの組み合わせの配列をオブジェクトに変換します。

簡単なサンプルはこんな感じ

```javascript

const array = [
  ['sample', 'data'],
  ['sample2', 100 ]
];

const obj = Object.fromEntries(array);

console.log(obj);
// { sample: "data", sample2: 100 }

```
配列からオブジェクトを生み出したい時に使っていました。

実際のプロダクトでは

Object.entriesの中でObject.fromEntriesをやっているところとかもあって、読み解くのに一苦労しました。笑

### スプレッド構文
配列のようなオブジェクト（正確には for of で展開できるもの）を個々の値に展開するのがスプレッド演算子です。
記法としては`...` とピリオド3つを使って表現します。

##### 配列の個々の値に展開する

```javascript
const data = [1, 2, 3, 8, 11];

console.log(Math.max(...data)); // 11

```

実際のプロダクトでは

```javascript

Math.max(
  ...this.dailyData.map(data => {
    return data.increaseCount;
  })
)
```
のようにして使っていました。


## おまけ（Typescript）


### enum
通常のJavascriptにはないもので、数値の定数に名前を付けて、その集合に対して定義ができるようにしたものです。
例えば

```typescript

enum userStatus {
  ready,
  active,
  finished
}
```
のようにセットすると。Javascript側では

```javascript

"use strict";
var userStatus;
(function (userStatus) {
    userStatus[userStatus["ready"] = 0] = "ready";
    userStatus[userStatus["active"] = 1] = "active";
    userStatus[userStatus["finished"] = 2] = "finished";
})(userStatus || (userStatus = {}));
```
のようにコンパイルされます。ちょっとややこしいですね。

実際に使う時にはこんな感じで使えるようになります。
（下記の場合だとVue.jsで使っています）

```vue
<template v-if="status === userStatus.ready">
  <!--userのstatusがreadyの時の内容-->
</template>
```

### generics
genericsは「抽象化されたデータ型」を表現する機能です。
似た感じの関数だけど型が違うケースにおいて、引数である型を抽象的に使う時に便利です。

どういうことかといいますと

* string型のデータを引数にしてstring型のvalueを持った配列を返す関数
* number型のデータを引数にしてnumber型のvalueを持った配列を返す関数

これらの2つがあった時に

```javascript
let stringArray = (valueOfString: string): string[] => {
  return [valueOfString, valueOfString, valueOfString];
};

let numberArray = (valueOfNumber: number): number[] => {
  return [valueOfNumber, valueOfNumber, valueOfNumber];
};

```
上記のように型をつけてもいいのですが、同じような形の関数を2つも書くのはめんどくさいし冗長ですよね。

なのでこれを


```javascript
let genericsArray = <T>(genericsValue: T): T[] => {
  return [genericsValue, genericsValue, genericsValue]
}
```
とTとして抽象化することで

```javascript

genericsArray<number>(10)
// [10,10,10]
```
genericsArrayの引数はnumber型で、かつ返り値もnumber型となってくれます。

`<number>`の箇所を
`<string>`にすれば

```javascript
genericsArray<string>(10)

// ["10","10","10"]
```
のようにできます。

うーん、これは味がありますね。

## 最後に
実際の開発の中では他にも色々なメソッドに触れましたが、全部は書けないので、この辺で。

来年は業務で使っているJavascript、Typescript、Nuxt.js以外にもPythonを触っていく予定です。もっとたくさんコードを書いて周りのすごいエンジニアの人とちゃんと対等に仕事ができるように頑張ろう。