JavaScriptことはじめ

# 概要と前提
実際にプログラムを動かしながら、JavaScriptの基礎を習得していくことを目的としています。プログラミング初級＆（ほぼ）はじめてJavaScriptに触れる人を対象にしています。また、ES2015以降のシンタックスで学んでいきます。

# 準備するもの
- Webブラウザ：Google Chrome
- エディタ：Atom (とか、なんでもよい)

# デバッグ方法の確認

Google Chromeのデベロッパーツールをつかう

- メニュー→その他のツール→デベロッパーツールを開く
- コンソールタブを開く

コンソールからできること

- エラーを確認できる
- インタラクティブにJavaScriptが実行できる

![image](https://qiita-image-store.s3.amazonaws.com/0/142277/458eb485-2b0e-a7e6-0cea-c5a5025d8d36.png)

##### Practice #0
下記のファイルを作成し、Webブラウザからアクセスしてデベロッパーツールを開いておく

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <h1>hello, world!</h1>
  </body>
</html>
```

##### Practice #1
下記のコードをコンソールで実行して、アラートがでることを確認する

```javascript:console
alert("hello, world!");
```

##### Practice #2 
下記のコードをコンソールで実行して、エラーが表示されることを確認する

```javascript:console
alert(a);
```

# 実行方法

`<script>`タグの中にプログラムを書いて、ブラウザをリロードすると実行される

##### Practice #3
下記のようにindex.htmlを編集して、コンソールに文字列が表示されることを確認する

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <h1>hello, world!</h1>
    <script type="text/javascript">
      console.log("hello, world!");
    </script>
  </body>
</html>
```

# JavaScriptの基礎

### コメント、変数
下記はコメントとして扱われ、プログラムとは認識されない

```javascript:script
//一行コメント

/*
複数行
の
コメント
*/
```

変数は、すべて`let`で宣言する

```javascript:script
let a = 0;
```

### データ型：数値と文字列

```javascript:script
let a = 1; // 数値 
let b = 'abc'; // 文字列はクォーテーションもしくはだぶるクォーテーションで括る
console.log("aは数値" + a);
console.log("bは文字列" + b)
```

##### Practice #4
上記のコードを実行して、変数a, bの中身がコンソールに出力されることを確認する（以降は、スクリプトタグの中に書いて実行すること）



### データ型：真偽値

```javascript:script
let a = true; // 真
let b = false; // 偽
console.log("a = " + a);
console.log("b = " + b)
```

##### Practice #5
上記のコードを実行して、変数a, bの中身をコンソールで確認する

### データ型：配列

```javascript:script
// 配列の宣言
let a = [];
let b = [1,2,3];

// 配列に要素を加える
a.push(1);
a.push(2);
a.push('hello, world');
b.push(4);

// 配列を参照する
console.log("a[0] = " + a[0]);
a[0] = 10;

console.log(a);
console.log(b)

// 配列の大きさ
console.log("aの要素数は " + a.length);
console.log("bの要素数は " + b.length);
```

##### Practice #6
上記のコードを実行して、コンソールで確認する

### データ型：undefined、null

```javascript:script
// undefined: 変数が初期化されていないことを示すデータ型（本当になにも入っていない）
let a;
console.log(a);

// null: 中身がないことを示すデータ型 (意図的にnullが入っていることを示す)
a = null;
console.log(a);
```

##### Practice #7
上記のコードを実行して、コンソールで確認する

##### Practice #8
変数aを宣言せずにconsole.log(a);を実行すると、`ReferenceError` となることを確認する（これは別のタイプのundefined）

### 算術演算子と代入演算子

```javascript:console
let a = 1, b = 3, msg = 'hello', c; 

// 四則演算と剰余
c = a + b; //-> 4
c = a - b; //-> -2
c = a * b; //-> 3
c = a / b; //-> 0.3333...
c = a % b; //-> 1
c = msg + 3; //-> 'hello3'

// 代入演算子
a = a + 1 //-> 2
b += 1; //-> 4

// インクリメント・デクリメント演算子
c = a++; // c=2, この文の実行後にaに1が加算される（a=3になる）
c = ++a; // c=4, この文の実行前にaに1が加算される（a=4になる）
c = a--; // c=?
c = --a; // c=?
```

##### Practice #9
上記のコードを１行ずつコンソールで実行して確認する

### 比較演算子と論理演算子

```javascript:console
let a = 1, b = 2, c = '1', d = 1;

// 比較演算子
a == c; // 左辺と右辺の値が等しい場合は true
a == d; // ?
a != b; // 等しくない場合は true
a < b; // 左辺より右辺が大きい場合は true
a <= b; // 左辺より右辺が大きいか等しい場合は true
a === c; // 左辺と右辺の値が等しい、かつデータ型も等しい場合は true 
a === d; // ?
a !== d; // ?

// 論理演算子
a == c && a == d; // AND
a == c || b == c; // OR
!(a == c); // NOT
```

##### Practice #10
上記のコードを１行ずつコンソールで実行して確認する

### 条件分岐

```javascript:script
// if文
let score = 80;
if (score >= 80) {
  console.log('very good')
} else if (score >= 60) {
  console.log('good')
} else {
  console.log('poor')
}

// 3項演算子
x = (score > 60) ? "good" : "poor";
console.log(x);

// switch文
let signal = "blue";

switch (signal) {
  case "red":
    console.log("stop!");
    break;
  case "green":
    console.log("go!");
    break;
  case "yellow":
    console.log("be careful!");
    break;
  default:
    console.log("wrong signal");
    
}
```
##### Practice #11
上記プログラムを<script></script>内に記述し、scoreの値を変更しながら動作確認をする

### 繰り返し

```javascript:script
// for文
for (let i = 0; i< 10; i++) {
  console.log(i);
}

// while文
let i = 0;
while (i <= 10) {
  console.log(i);
  i++;
}
```
##### Practice #12
上記プログラムを実行し、コンソールになにが表示されるかを確認する


### 関数

```javascript:script
// function文による定義（実行前に定義される）
function hi(name) {
  return "hi, " + name;
}
console.log(hi("Taro"));

// 関数リテラルによる定義 (実行されるときに定義される)
let bye = function(name) {
  return "bye, " + name; 
};
console.log(bye("Taro"));
```
##### Practice #13
上記プログラムを実行し、コンソールになにが表示されるかを確認する

##### Practice #14
上記プログラムでconsole.logを関数定義の前で呼び出すとどうなるかを確認する


### よくつかう組み込みオブジェクト

```javascript:script
// Arrayオブジェクト
let arr = new Array(2);　
arr[0] = 1;
arr[1] = 2;
arr.push("hello");
console.log(arr);

//（補足）2次元配列
let arr_2d = new Array(3);
for(let i = 0; i < 3; i++) {
  arr_2d[i] = new Array(3);
  for(let j = 0; j < 3; j++) {
    arr_2d[i][j] = 0;
  }
}

// Dateオブジェクト
let now = new Date();
console.log(now);
now.setMonth(now.getMonth() + 3);　//３か月後
now.setDate(now.getDate() + 3); //3日後
now.setHours(now.getHours() + 3); //3時間後
now.setMinutes(now.getMinutes() + 3); //3分後
console.log(now);

// Mathオブジェクト
let random = Math.random(); // 0.0-1.0の乱数
console.log(random); 
let round = Math.round(random); // 四捨五入
console.log(round);
let y = Math.sin(Math.PI/2.0); // サイン関数
console.log(y);
```

##### Practice #15
上記プログラムを実行し、コンソールの表示を確認する


### ハッシュ（連想配列）
ハッシュとは、名前をキーにしてアクセスできる配列のこと。ドット（．）でキー名を指定してアクセスする

```javascript:script
// ハッシュ
let user = {
  name : 'taro', // key = name, value = taro
  age : 20,
  gender: 'male'
};

// キーを指定してアクセス 
console.log(user['name']);
console.log(user.name);

// 値を変更
user.age = 30;
console.log(user.age);

// キーを追加
user['password'] = '123456789';
user.hobby = 'football';
console.log(user);

```

##### Practice #16
上記プログラムを実行し、コンソールの表示を確認する

### オブジェクト
オブジェクトとはオブジェクト指向プログラミングにおけるもっとも重要な概念です。
その特徴として、カプセル化、継承、ポリモーフィズムの３つがよく挙げられますが、もっとも重要なものはカプセル化です。
カプセル化とは、データと手続きをまとめることです（ここで手続きとは関数とかでまとめられる処理のこと）。そして、オブジェクトとは、データと手続きをまとめてくれる何かです。

JavaScriptにおけるオブジェクトは、実はハッシュと同じものです。が、ハッシュをオブジェクトとしてみるとすこし呼ばれ方が変わります。オブジェクトがもつデータをプロパティとよび、手続きをメソッドと呼びます。

```javascript:script
// オブジェクトをつくる
let user = {
  // プロパティ
  name : 'taro',
  // メソッド
  hello : function(){
    console.log("hi, I am " + this.name);
  }
};

// userオブジェクトのメソッド呼び出し
user.hello();

// userオブジェクトのプロパティにアクセス
user.name = 'hanako';
user.hello();

// userオブジェクトのメソッド追加
user.bye = function(){
  console.log("bye, " + this.name);
};
user.bye();
```
##### Practice #17
上記プログラムを実行し、コンソールの表示を確認する

### クラス
ES2015以降、class命令がつかえます。それまでは、javascriptにclass命令はなく、プロトタイプベースのオブジェクト指向（超訳すると、オブジェクトをコピーしてつかっていくタイプのオブジェクト指向）と称されていました。ただ、クラスが入ったためにこの呼び方は微妙になりましたが、いまでもプロトタイプは健在です。

```javascript:script
// クラス定義
class User {
  // コンストラクター
　constructor(firstName, lastName){
    this.firstName = firstName;
    this.lastName = lastName;
  }
  // メソッド
  getName(){
    return this.firstName + " " + this.lastName;
  }
}

// インスタンス化
let u = new User('Taro', 'Yamada');
console.log(u.getName());
```

### Windowオブジェクト
JavaScriptでは、ブラウザに対して様々な操作をおこなうことができるAPIが用意されています。それが、Windowオブジェクトです。とりあえず、Windowオブジェクト=ブラウザと考えてください。

```javascript:script
console.log(window);
```

##### Practice #18
上記プログラムを実行し、windowオブジェクトがもつプロパティとメソッドを確認する

### DOM
Document Object Model (DOM)とはHTML文書の構造を定義するもので、ツリー構造になっている。トップレベルにはDocumentという要素があり、その下にhtml要素がある。

W3C (http://www.w3.org/DOM) より抜粋
>“The Document Object Model is a platform-and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page. This is an overview of DOM-related materials here at W3C and around the web. ” 

```javascript:script
console.log(document);
```

##### Practice #19
上記プログラムを実行し、現在のHTML文書の構造を確認する

### DOM操作 #1: getElementByIdメソッド

また、documentはオブジェクトでもあり、DOM操作のためのプロパティとメソッドをもっています。また、htmlの各要素もオブジェクトであり、それぞれプロパティとメソッドをもっています。詳しくは下記のリンクを参照。
https://developer.mozilla.org/ja/docs/Web/API/Document

```html:html
<body>
  <div id="sandbox"></div>
  <script type="text/javascript">
    // idで指定したhtml要素の取得
    let element = document.getElementById('sandbox');
　　// 取得した要素に文字列を表示する
    element.textContent = "Hello, World!";
  </script>
</body>
```

##### Practice #20
上記プログラムを実行し、documentオブジェクトのメソッドgetElementById()をつかって、要素を取得して、その要素に文字列をセットできることを確認する。


### DOM操作 #2: styleプロパティ

```html:html
<body>
  <h1 id="text1" style="color: blue">Hello!</h1>
  <script type="text/javascript">
    let elm = document.getElementById('text1');
    elm.textContent = 'こんにちは！';
    elm.style.color = 'gray';
  </script>
</body>
```

##### Practice #20
上記プログラムを実行し、scriptなしで実行してみる。つぎにscriptでどのように変化するかを試してみる。また、colorに'red'や'black'、'purple'などに変更して動作確認する。

### DOM操作 #3: createElement, appendChildメソッド

```html:html
<body>
  <h1 id="text1" style="color: blue">Hello!</h1>
  <script type="text/javascript">
    // 要素を取得
    let elm = document.getElementById('text1');
    elm.textContent = 'こんにちは！';
    elm.style.color = 'gray';
　　// 新しい要素を作成
    let elm2 = document.createElement('h2');
    elm2.textContent = 'こんばんは！';
　　// bodyの子要素として追加
    document.body.appendChild(elm2);
  </script>
</body>
```

##### Practice #21
上記プログラムを実行し、scriptなしで実行してみる。つぎにscriptでどのように変化するかを試してみる。

##### Practice #22
上記プログラムを実行し、developer toolのElementタブでDOM構造を確認する。


### イベントリスナ
ウェブブラウザはマウスクリックやマウスオーバーなど様々なユーザからのイベントが発生します。これらのイベントにあわせて、特定の動作を実行するためにはイベントリスナを利用します。
イベントリスナは、element.addEventListener(`イベント名`, `イベント発生時におこなう処理`); のように要素に設定します。

```html:html
<body>
  <button id='btn'>アラート</button>
  <script type="text/javascript">
    // 要素を取得
    let btn = document.getElementById('btn');
    // イベントリスナを追加
    btn.addEventListener('click', function() {
      alert('Hello!');
    });
  </script>
</body>
```

##### Practice #23
上記プログラムを実行して、動作を確認する。