Node.js, JavaScript学習まとめ

# 今回の学習のゴール
1. Node.jsについて知る
2. 基本文法を学ぶ
3. ライブラリを把握する

# 目次
1. Node.jsとは
2. そもそもJavaScriptとは
3. JavaScriptの基本知識
4. Node.jsの基本知識
5. ライブラリの把握
6. 今後の課題

# 1. Node.jsとは
> スケーラブルなネットワークアプリケーションを構築するために設計された非同期型のイベント駆動のJavaScript環境
[Node.js](https://nodejs.org/ja/)

- それぞれの意味
    - スケーラブル : 拡張性が高い
    - 非同期 : 各要求(request)の処理が完了するのを待たずに、それ以降の処理を行う方式
    - イベント駆動 : イベントと呼ばれるアプリや端末上で起きた出来事に対して処理を行うプログラムの実行形式
- 特徴
    - サーバーサイドで使用できる
    - ノンブロッキングI/Oモデルを採用しており、I/Oの処理を待たずに次の処理を始めることができるので、大量のデータ処理が可能
        - ノンブロッキング : ある処理を行いながら、ほかの処理も同時進行で行えること
        - I/O : Input/Outputの略で、入出力の意


→ 大変理解に苦しんだので...
「Node.jsは、サーバー側の処理をJavaScriptで実装できる」ということは押さえておこう

# 2. そもそもJavaScriptとは
- ブラウザに実行エンジンが搭載されたプログラミング言語
    - クライアント側のパソコンやスマートフォンに搭載されているWebブラウザがプログラムを実行する
- Netscape Navigatorというブラウザ向けに開発され、その後Internet Explorer, Firefox, Chromeなどの主要ブラウザに採用された
- 特徴
    - ブラウザで動作する
    - 実行エンジンの内部で動的にコンパイルが行われるので、コンパイルしなくとも実行できる
    - 動的型付け言語

- [JavaScript - Wikipedia](https://ja.wikipedia.org/wiki/JavaScript) によると

>JavaScriptはプロトタイプベースのオブジェクト指向スクリプト言語であるが、クラスなどのクラスベースに見られる機能も取り込んでいる

- それぞれの意味
    - オブジェクト指向スクリプト言語
        - オブジェクトを組み立てるように表現して、コンピュータに動作をさせ、script（台本、原稿）のようにプログラムを記述できるプログラミング言語
    - プロトタイプベース
        - 全てのオブジェクトがプロトタイプ（試作品）をベースにして作られているもの
        - プロトタイプと呼ばれるテンプレートをコピーして、新しいオブジェクトが作られるイメージ
    - クラスベース
        - 全てのオブジェクトがクラスをベーシにして作られているもの
        - クラスはオブジェクトを作る設計書のことで、クラスそのものの名前、属性、処理の3つの要素を持つオブジェクトをまとめて定義したもの

![js.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529506/e92d4c1b-e115-1777-22e2-a922484b5e5b.jpeg)

# 3. JavaScriptの基本知識

### データ型
- String : 文字列
- Number : 数
- Boolean : 真偽値
- Null : 値が存在しないまたは無効なオブジェクト
- Undefined : 値を代入していない変数の値
- Array : 複数の値を格納可能
- Object : 基本的に何でも格納可能

```javascript
// 文字列を整数に変換するメソッド
parseInt('030', 10);    // 第2引数には変換の基数, 30が返される
parseInt('hello', 10);    // NaN(非数  "Not a Number" の略)が返される
```
```javascript
// 文字列の操作方法
'hello'.charAt(0); // "h"を返す
'hello, world'.replace('hello', 'goodbye'); // "goodbye, world"を返す
'hello'.toUpperCase(); // "HELLO"を返す
```

### 演算子

```javascript
1 + 1;                          // 数字を加える
'Hello' + 'world';              // 文字列の結合
10 - 1;                         // 減算
2 * 3;                          // 乗算
10 / 2;                         // 除算
```
```javascript
var myVariable = 'value';       // 代入
myVariable === 'value';         // 等価 値と型が等しいか真偽値で返す 変数myVariableにvalueが代入されている場合は、trueが返される
!(myVariable === 'value');      // 否定 値と型が等しくないか真偽値で返す
myVariable !== 'value';         //非等価 値と型が等しくないか真偽値で返す
weather === 'sunny' && temperature < 25    // AND 2つ以上の式を1つに繋げそれぞれの式を個別に評価、全てtrueになった場合その式全体がtrueを返す
weather === 'sunny' || temperature < 25    // OR 2つ以上の式を1つに繋げそれぞれの式を個別に評価し、最初にtrueになったところでその式全体をtrueとして返す
```
```javascript
x += 5;    // 変数xの値を5増やす x = x+5の意味　複合代入文という
```

### 変数
- varを用いた変数の宣言

```javascript
var <変数名>;    // 変数の宣言
<変数名> = '値';    // 変数に値を割り当て, 変数の値を変更する
var <変数名> = '値';
<変数名>;    // 変数の値を取得
```
- 変数のスコープは関数単位

```javascript
function f() {
    var num = 123;
    console.log(num);
    {
    var num = 456;
    console.log(num);
    }
    console.log(num);
}
f();

// 実行結果
123
456
456
```
- letを用いた変数の宣言

```javascript
let <変数名> = '値';    // ブロックレベルの変数を宣言
```
- 変数のスコープがブロックに限定される

```javascript
function f() {
    let num = 123;
    console.log(num);
    {
    let num = 456;
    console.log(num);
    }
    console.log(num);
}
f();

// 実行結果
123
456
123
```

### 定数

```javascript
const number = '10';    // 定数の宣言 一度宣言された値は変更不可
```

### 配列

```javascript
// 配列を生成する①
var person = new Array();
person[0] = 'たなか';
person[1] = 'なかむら';
person[2] = 'しぶや';

// 配列を生成する②
var person = ['たなか', 'なかむら', 'さいとう']

// 配列に要素を追加する
person.push(いとう);
```

### 条件文 if

```javascript
var color = 'red'
if (color === 'red') {         // (条件式)がtrueを返した場合、以下の処理が実行される
    alert('好きな色は赤です');    // アラートを使って表示
} else if (color === blue) {
    alert('好きな色は青です');
} else {                       // 2つの(条件式)がfalseを返した場合、elseの後の処理が実行される
    alert('好きな色は黄色です');
}
```
### switchステートメント

```javascript
var color = 'red'
switch (color) {
  case 'red':
    alert('好きな色は赤です');
    break;    // 値がcaseにマッチした時ループを抜ける

  case 'blue':
    alert('好きな色は青です');
    break;
    
  // 以下に選択肢を好きなだけ並べることが可能

  default:
    alert('選択肢に好きな色がありません');
}
```

### ループ
- カウンター : ループの開始地点で、初期化される値
- 終了条件 : ループが終了する条件
- イテレーター : 終了条件を満たすまで、カウンターの値をループごとに少量ずつ増加（減少）させる

```javascript
// forを使ったループ
var sequence = [1, 2, 4, 7, 11, 16, 22];
for (var i = 0; i < sequence.length; i++) {    // カウンター変数を宣言 lengthプロパティを使用して配列の長さを取得し、ループを配列の長さと同じ数になったら、繰り返しを終了
  console.log(sequence[i]);
}
```

```javascript
// whileを使ったループ
var sequence = [1, 2, 4, 7, 11, 16, 22];
var i = 0;    // 初期化処理
while (i < sequence.length) {
    console.log(sequence[i]);

    i++;
}
```

```javascript
// do...whileを使ったループ
var sequence = [1, 2, 4, 7, 11, 16, 22];
var i = 0;
do {
    console.log(sequence[i]);

    i++;
} while (i < sequence.length)
```

### 関数
- 再利用したい機能をパッケージ化する方法

```javascript
function sayHello() {
  alert('hello');
}

sayHello();    // functionの呼び出し helloのアラートが表示される
```

```javascript
function sum(num1, num2) {    //関数の定義 関数に複数の引数がある場合はカンマで区切る
    var result = num1 + num2;
    return result;
}
```
```console
sum(1, 2);    # コンソールで実行すると3が返ってくる
```

### イベント
- ブラウザの中で起きていることを検出し、その応答としてコードを実行する
- 動作や操作（以下の例ではクリック）に対して特定の処理を与えるための命令のことをイベントハンドラという
- ブラウザに組み込まれたJavaScript APIの一部として定義されたもの

```javascript
var page = document.selector('html');    // 関数を定義し変数に代入
page.onclick = function() {    // 無名関数は主にイベント発火のレスポンスとして、一連のコードを走らせるだけのような場合に、イベントハンドラとして使われる
    alert('ページがクリックされた');
};
```

### オブジェクト
- 関連のあるデータと機能をひとまとめにしたモノ
- 機能はたいてい変数と関数で構成され、オブジェクトの中ではそれぞれプロパティとメソッドと呼ばれる

```javascript
var obj = new Object();    // 空のオブジェクトを作成する方法①
var obj = {};    // 空のオブジェクトを作成する方法②オブジェクトリテラル構文
```
- オブジェクトリテラル使用してオブジェクトを生成する例

```javascript
var person = {
  name: ['たかはし', 'なかむら'],
  age: 20,
  gender: 'female',
  greeting: function() {    // オブジェクトのメソッド
    alert('こんにちは、' + this.name[1] + 'と申します。' + this.age + '歳です。');    // thisは現在のオブジェクトを参照しているので、personを指す
  }
};
```
```javascript
# コンソールで実行

person    # {name: Array(2), age: 20, gender: "female", greeting: ƒ} と返ってくる
person.name[1]    # "なかむら" と返ってくる
person.greeting()    # こんにちはなかむらと申します。20歳です。 とアラートが返ってくる
person.age = 30;    # 値を上書きすることができる
```

```javascript
// サブ名前空間でオブジェクト生成するときの記載方法

name: {
  first: 'たかはし',    // name.firstで"たかはし"が返ってくる
  second: 'なかむら'    // name.secondで"なかむら"が返ってくる
}
```

### 継承
- ”親”クラスからの機能を継承する”子供”のオブジェクトクラス (コンストラクタ) の生成方法について

```javascript
// コンストラクタ内部にプロパティのみを定義
function Person(first, second, age, gender) {
    this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
};

// メソッドはすべてコンストラクタのプロトタイプとして定義する
Person.prototype.greeting = function() {
  alert('こんにちは、' + this.name.first + 'と申します。' + this.age + '歳です。');
};

// Personコンストラクタの子であるTeacherコンストラクタを作成
function Teacher(first, second, age, gender, subject) {
  Person.call(this, first, second, age, gender);    // call()関数 その他の場所で定義された関数から呼ぶことができる

  this.subject = subject;    // Teacherだけが持つプロパティを定義
}
```

### JSON（JavaScript Object Notation）
- JavaScript オブジェクトの構文に従ったテキストベースのフォーマット
- ウェブアプリケーションでデータを転送する場合に使われる
- MIME type（メディアタイプ）がapplication/jsonで、「.json」という拡張子の付いたテキストファイルとしてJSON自身を格納することもできる（以下その例）

```json
{
  "companyName": "Super heroes",
  "homeTown": "Central City",
  "formed": 2005,
  "active": true,
  "members": [
    {
      "name": "Takahashi",
      "age": 28,
      "business description": [
        "labor management",
        "Payroll"
      ]
    },
    {
      "name": "Nakamura",
      "age": 35,
      "business description": [
        "Disclosure",
        "Payment",
        "Sales recording"
      ]
    }
  ]
}
```
- このオブジェクトをJavaScriptのプログラムへ読み込む（excellenceという変数に代入したとすると）と、ドットや角括弧を使ってデータへアクセスすることができる
※JSONでは文字列とプロパティ名をシングルクォートではなく、ダブルクォートで括る

```javascript
excellence.companyName
excellence['members'][1]['business description'][0]    // 2番目のメンバーの1番目の業務内容を参照
```

### Web API
- Application Programming Interfacesの略
- 開発者が複雑な機能を簡単に作成できるように、プログラミング言語から提供される構造のこと
- ブラウザやサイトが動作しているOSの様々な面を操作したり、他のWebサイト、サービスから取得したデータを操作するためのプログラムされた機能である
- APIのカテゴリ
    - ブラウザAPI : Webブラウザに組込まれているAPIで、ブラウザやコンピュータの環境の情報を取得して複雑な機能を簡単に実装できる（ex. Geolocation API）
        - ブラウザで読み込んだ文書を操作するためのAPI, サーバからデータ取得をするAPI, クライアント側でのデータ保持APIなどがある
    - サードパーティAPI : サードパーティのプラットフォーム（TwitterやFacebook）上に作られた構造で、それらの機能をWebページで利用できるようにする（ex. Twitter API, Google Maps API, YouTube API）

### クロージャ
- 関数とその関数が作られた環境が一体となった特殊なオブジェクトのこと
- あるコードブロック内で定義された関数などが、そのブロックをスコープとする変数などを参照できる
- オブジェクト内部で使用している変数やメソッドを他のプログラムから容易に変更できないようになる（カプセル化）
- ex. 関数createStopwatchのスコープ内で定義された変数timeと関数の結果が一体となったオブジェクトを変数stopwatchへ代入しているため、変数stopwatchが呼び出される都度、変数timeは0に初期化されることなく、下記のような結果が返ってくる

```javascript
var createStopwatch = function() {
    var time = 0;
    return function() {
        time += 1;
        console.log(time);
    };
};
var stopwatch = createStopwatch();
stopwatch();    // 1が返ってくる
stopwatch();    // 2が返ってくる
stopwatch();    // 3が返ってくる
```

# 4. Node.jsの基本知識
### Hello, Nodeを出力

```javascript:hello.js
console.log('Hello, Node')
```
- プログラムを実行

```console
$ node hello.js
```
- 実行結果

```console
Hello, Node
```
- 'use strict';を宣言するとstrict（厳格）モードで実行できる
    - strictモード : javascriptのコードをより厳しくエラーチェックすることができる仕組み

```javascript:hello.js
'use strict';    
console.log('Hello, Node')
```

- Webサーバとして動作させる場合
 
```javascript:hello2.js
var http = require("http");    // HTTPモジュールの読み込み

http.createServer(function(request, response) {    //  HTTPサーバを作成
   response.writeHead(200, {'Content-Type': 'text/plain'});    // レスポンスHTTPヘッダーを設定
   response.end('Hello, Node\n');    // レスポンスボディを送信
}).listen(8000);    // ポート8000でリクエストを行う

//  サーバにアクセスするためのURLを出力 
console.log('Server running at http://127.0.0.1:8000/');
```
- プログラムを実行

```console
$ node hello.js    // ブラウザで"http://localhost:8000"にアクセス Hello, Nodeと表示される
```

### 非同期処理
- 処理を実行したら結果を待たずに他の処理を実行できる（複数の処理を平行して実行できる）
    - 同期処理は、上から下へ1行ずつ順番にプログラムが実行されていく（サーバーへアクセスをして値を取得する間プログラムはストップしている）

```javascript
// 操作が完了する前に次の処理を実行する
setTime(function() {
   console.log('First');
   }, 3000);    // 処理に3秒間かかる
console.log('Second');
```
- 実行結果

```console
Second
First
```

- Node.js ではPromiseという仕組みを使って非同期を実現
    - Promiseとは非同期処理を実現するために用意されたオブジェクト
    - 非同期処理の成功時(resolve)、失敗時(reject)の処理を明示的に書くことが出来る

```javascript
var promise = new Promise(function(resolve, reject) {    // Promiseオブジェクトを変数に代入
  setTimeout(function() {
    resolve('hoge');    // 処理成功時にresolveが呼ばれる 引数に返したい結果となる値を指定
  }, 3000);
});

promise.then(function(value) {    // then()の中の関数の引数valueにPromiseの結果が格納されいる
  console.log(value);    // 3秒待ってhogeが返されることが約束されている
});

console.log(promise);    // [object Promise]が返される
```
実行結果

```console
[object Promise]
hoge
```

# 5. ライブラリの把握
- [axios](https://github.com/axios/axios)
    - HTTP通信を簡単に行うことができるJavascriptのライブラリ
- [request](https://github.com/request/request)
    - 標準のhttpライブラリを使うより簡単で理解しやすい記述でHTTP通信を行うことができるライブラリ
- [Moment.js](https://momentjs.com/)
    - JavaScriptで日付を扱うためのライブラリ
    - 日時の加算減算や2つの日付の差の計算などができる
- [facebook/jest](https://github.com/facebook/jest)
    - JavaScriptのテストフレームワーク

# 6. 今後の課題
- npm（Node.jsのパッケージを管理するもの）を学習する際に、Node.jsについての理解を深める

## 参照
- [オブジェクト指向とは何か？わかりやすい例で説明してみた。](https://www.sejuku.net/blog/5973)
- [オブジェクト指向がわからない！ そんなあなたの脳味噌をオブジェクト脳にする準備体操](https://codezine.jp/article/detail/10215)
- [イメージで理解する「プログラミング初心者が確実に意味不明になる”オブジェクト指向プログラミング”ってなんなのさ」](https://tec.citrussin.com/entry/2015/08/13/155115)
- [クラスベースとプロトタイプベース](https://prime503.hatenadiary.org/entry/20091225/1261720985)
- [【Node.js入門】JavaScriptとの違いや特徴・使い方を比較してみた！](https://www.sejuku.net/blog/86748)
- [MDN web docs - JavaScripyの基本](https://developer.mozilla.org/ja/docs/Web/JavaScript)
- [MDN web docs - Express/Node のイントロダクション](https://developer.mozilla.org/ja/docs/Learn/Server-side/Express_Nodejs/Introduction)