JavaScript入門

参考：http://dotinstall.com/lessons/basic_javascript_v2

#JavaScript

ブラウザに実装されているスクリプト言語
動きのあるウェブサイトにできる
※Javaとは別物

##リファレンス
mdn javascript


##主な構造
```lang:html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>JavaScriptの練習</title>
</head>
<body>
   <script src="myscript.js"></script>
   <script>
     /* 
        コメント
        コメント
        コメント
     */
     // コメント
      console.log("hello world!");
   </script>
</body>
</html>
```
※scriptタグは/bodyの直前

## 変数とデータ型

###変数とは

データにつける名前
複雑なデータに名前をつけ、それを使って演算や使いまわしができる
`var msg;`

文字列を割り当てる
` msg = "hello world!";`
※=は代入演算子（右辺のものを左辺に代入）

変数を呼び出す
→例：コンソールにmsgを出力する
`console.log(msg);`
※console.logとは
→http://uhyohyohyo.sakura.ne.jp/javascript/11_3.html
→http://d.hatena.ne.jp/keyword/console.log

一気に書くことが可能
`var msg = "hello world!",
　　　x  = 20,
　　　y  = 12;`

###JavaScriptに用いられるデータ型
* 文字列
* 数値
* 真偽値（true / false）
* オブジェクト（配列、関数、組み込みオブジェクト）
* undefined　定義されていない
* null　何もない


## 数値と演算子

数値
10,2.5,-2.5

演算子
+,-,*,/,%(余り)
+=,*= 代入を伴う演算子
++,-- 単項演算子(x++,++x)

演算
`<script>
　var x;
　x = 10 * 2; // 20
　x = 10 % 3; // 1
　x = x + 5; // 1+5=6
　x += 5; // 上と同じ
　x++; // 6+1=7
　x--; // 7-1=6 
　console.log(x);
</script>`

## 文字列の使い方

文字列の表示
`<script>
　var s;
　s = "hello";
　s = 'hello';  
　s = "it\'s\n a pe\tn.";
　console.log(s);
</script>`

* ",'はどちらでも可
* \' 'を表示するためのスラッシュ
* \n 改行
* \t タブ

文字列の連結
`s = "hello" + "world";`

片方が文字列の場合、数字であっても文字列の連結になる
`s = "5" + 5 // ×10　→　"55"`


## if文を使う

条件分岐
`if(条件)  {
真の処理 
}　else {
偽の処理　
}`

点数によって文字列を変える
`<script>
　var score = 50;
　if (score > 68) {
　　console.log("ok!");
　} else if (score > 40) {
　console.log("soso...");
　} else {
　console.log("ng!");
　}
</script>`

###比較演算子

* >,<　（大きい、小さい）
* >=,<= （何々以上、何々以下）
* ===,==　（何々と等しい）
* !==,!=　（何々と等しくない）

###論理演算子（条件を更に組み合わせるためのもの）　

* AND,&&
* OR,||
* NOT,!

例
`score > 60 && score < 88`


## 真偽値と三項演算子

###真偽値
* 文字列： 空文字以外だったらtrue
* 数値： 0 か NaN 以外だったらtrue
* true / false
* object:  null 以外だったらtrue
* underfined, null -> false

`if(x) {
     処理
}`
は↓と同じ（xが空文字以外だったらtrue）
`if(x !=='') {
     処理
}`    

###三項演算子
`var a, b, c;
　if(条件) {
　　a = b;
　} else {
　　a = c;
　}`
は↓と同じ
`a = (条件) ? b : c;`

例
`var max, x, y;
max = (x > y) ? x : y;`

※初心者のうちはif-else文をちゃんと書く


## switch文を使う
条件分岐 switch
`<script>
　var signal = "red"; //シグナルが赤の時
　switch(signal) {
　　case "red":
　　console.log("stop!");
　　break; // break忘れないように
　　case "green":
　　console.log("go!");
　　break; 
　　case "yellow":
　　console.log("slow down!");
　　break;
　　default:
　　console.log("wrong signal");
　　break; 
　}
</script>`

## while, do ...whileを使う
ループ処理

* while
* do ... while

条件が真である場合、この条件を続ける
0から1ずつ増やして9でストップしたものを表示
`<script>
　var i = 0;
　while (i < 10) {　// 真
　console.log(i);
　i++;
　}
</script>`
は↓と同じ
`<script>
　var i = 0;
　do {
　console.log(i);
　i++;
　} while (i < 10);　//真
</script>`
※条件判定が行われるタイミングがちがう
　（後者は一度実行される）
→i=200だった場合、whileでは初めに偽ではじかれるがwhile doは実行される

## for文を使う
forもループ処理
`for (var i = 0; i < 10; i++) {
  console.jog(i);
}`
※whileと同じだが一文で済む


## ループを抜ける処理

* break：ループ処理を抜ける
* continue：ループ処理を1回スキップ

`for (var i = 0; i < 10; i++) {
  if (i === 5) {
    break;
    }
  console.jog(i);
}`

`for (var i = 0; i < 10; i++) {
  if (i === 5) {
    continue;
    }
  console.jog(i);
}`

## alert,confirm,promptを使う
### アラート
`<script>
alert("hello");
</script>`

### 質問
`<script>
var answer = confirm("are you sure?");
console.log(answer);
</script>`
※返り値があり、この場合answerという変数に格納される。
　→conflimの場合は true / false
↓のように使える
`if (conflim("本当に削除しますか？")) {
   削除処理
}`

### 入力のある質問
`var name = prompt("お名前は？","名無しさん");
console.log(name);`
※この場合nameという変数に格納される。
　→入力が返ってくる／キャンセルを押すとnullが返ってくる
※名無しさん＝初期値



## 関数を使う
複数の処理をまとめ、名前をつけたもの
（同じような処理を繰り返し書くとき、使いまわしができる）
`function 関数名() {
  処理
 }`

helloという関数に処理を指定する
→コンソールにhelloと表示
`<script>
　function hello() {
　　console.log("hello");
　}
　hello(); //呼び出し　
</script>`

関数にオプションを与える
（似たような処理があり、そこだけ変えたいときに使う）
`function 関数名(引数) {
  処理
 }`

`<script>
　function hello(name) { //name：引数用の変数名を付ける　
　　console.log("hello" + name); //処理の中で利用
　}
　hello("Tom"); //引数用の変数に値を与えて呼び出し　
　hello("Bob");
</script>`
※(name, ... ) 引数は複数設定できる

関数から返り値をもらいたいとき
`function 関数名() {
  処理
  return 返り値
 }`

`<script>
　function hello(name) { 
　　return "hello" + name ; 
　}
　var greet = hello("Tom"); // greetという変数を設定
　console.log(greet); //consoleにgreetを表示
</script>`



## ローカル変数
関数内で宣言した変数にはルールがある。

ローカル変数はその関数内でしか有効でない
→helloの中にmsgという変数を宣言する
`<script>
  function hello(name) {
    var msg = "hello" + name; 
    return msg ; 
  }
  var greet = hello("Tom"); 
  console.log(greet);
  console.log(msg); // Error
</script>`

## 関数の別の書き方
関数もデータ型なので変数に入れることが可能。
`<script>
　ver hello = function(name) { //関数名は省略できる（無名関数、匿名関数）
　　var msg = "hello" + name; 
　　return msg ; 
　}; // 必ず;をつけるように
　var greet = hello("Tom");
　console.log(msg); 
</script>`

## 即時関数
関数を宣言してすぐに実行できる関数
`<script>
　(function hello() {
　　console.log("hello");
　})();
</script>`

引数をとることも可能
`<script>
　(function hello(name) {
　　console.log("hello" + name);
　})("Tom");
</script>`

※関数名（hello）を省略することも可能

自分が書いたプログラムの変数を、他の人のプログラムから影響を受けたり
他の人の変数に影響を与えたりしないローカル変数にするにも使われる
`<script>
　ver x = 10,
　　　y = 20;
　console.log(x + y);
</script>`
を囲ってローカル変数にする
`<script>
　(function() {
　ver x = 10,
　　　y = 20;
　console.log(x + y);
})();
</script>`
→関数内で定義された変数は外からアクセスできないので、
即時関数で囲うことによって変数を安全に使うことができる
→他の人のプログラムを読み込みながらコードを書くようになると必要
複雑なコードを書くようになったら心がけること


## setInterval, setTimeoutを使う
タイマー処理を行う

* setInterval ある一定の時間ごとにある処理を繰り返す
* setTimeout ある時間後にある処理を1回だけ実行する

0からある一定の時間ごとにカウントアップする
setInterval
`<script>
　var i = 0;
　function show() {
　　console.log(i++); //カウントアップ
　}
setInterval(function() { //ここでしか使わないので無名関数
　　show(); 
　}, 1000);  //引数はミリ秒で指定(1000=1秒)
</script>`
setTimeout
`<script>
　var i = 0;
　function show() {
　　console.log(i++); 
　}
setTimeout(function() { 
　show(); 
　}, 1000);  
</script>`

setIntervalは前の処理を考慮せず処理を続けるが、setTimeoutは前の処理が終わったことを確認してから実行する
→繰り返し処理にはsetTimeoutの方がよく使われる

setTimeoutを繰り返し処理に使うには
`<script>
　var i = 0;
　function show() {
　　console.log(i++); 
　　setTimeout(function() {
　　　show();　//showの中でshowを呼び出すのでループ
　　}, 1000);
　}
　show(); // 最初だけ呼び出しが必要
</script>`

タイマーの止め方
setTimeoutに名前をつけてから（var tid =）、clearTimeoutの設定（tid）
`<script>
　var i = 0;
　function show() {
　　console.log(i++); 
　　var tid = setTimeout(function() {
　　　show();　//showの中でshowを呼び出すのでループ
　　}, 1000);
　　if (i > 3) {
　　　clearTimeout(tid);
　　}
　}
　show(); // 最初だけ呼び出しが必要
</script>` 


## 配列を使う
複数のデータをまとめることができる
`<script>
 // var score = 100, score_2 = 200;
　var score = [100, 300, 500];
　console.log(score[0]); //添え字は0から始まるので上記100なら0 
</script>`

書き換えたいとき
`score[2] = 400;`

全て表示させるとき
`console.log(score);`

いろいろなデータ型を混ぜることも可能
`var score = [100, 300, 500, "taguchi"];`

配列の中に配列を入れることもできる
`<script>
　var m = [
　[1, 2, 3],
　[4, 5, 6]
　];
　console.log(m[1][1])
</script>`
※[1, 2, 3]と[4, 5, 6]で2番目なので[1]
　[4, 5, 6]の2番目なので[1]

## オブジェクトを使う
配列と同じくグループ化されたデータ
オブジェクト：名前と値のペアをグループ化することができる
`<script>
　var user = {
　　email: "taguchi@gmail.com". //プロパティ、名前：プロパティ名 
　　score: 80
　};
　console.log(user["email"]); //値の呼び出し方1
　console.log(user.email); //値の呼び出し方2
</script>`

値の書き換えも可能・オブジェクトの表示
`user.score = 100;
 console.log(user);`


## メソッドを使う
オブジェクトはプロパティの値に関数を持つことも可能

名前という引数を受け取り、それに対して挨拶する
`<script>
　var user = {
　　email: "taguchi@gmail.com", //プロパティ、名前：プロパティ名 
　　score: 80,
　　greet: function(name) {  //関数を仕込む・無名関数で
　　　console.log("hello, " + name);
　　}
　};
　user.greet("Tom");
</script>`
※オブジェクトのプロパティの値に関数が来た場合、その関数のことをオブジェクトのメソッドと呼ぶ

メソッド内でthisというキーワードを使うと、今自分がいるオブジェクトを参照することができる
→オブジェクト内の他のプロパティにもアクセスできる
`<script>
　var user = {
　email: "taguchi@gmail.com", //プロパティ、名前：プロパティ名 
　score: 80,
　greet: function(name) {  //関数を仕込む・無名関数でよい
　　console.log("hello, " + name + " from " + this.email); // this = user
　　}
　};
　user.greet("Tom");
</script>`

## Stringオブジェクトを使う
### 組み込みオブジェクト：あらかじめ用意されているオブジェクト

* String：文字列に関するオブジェクト 
* Array：配列に関するオブジェクト
* Math：数学に関するオブジェクト
* Date：日付に関するオブジェクト

`<script>
　var s = new String("taguchi"); //何の文字列に対して作りたいかを引数で渡す
　console.log(s.length);
</script>`
sに対していろんなメソッドやプロパティが使えるようになる
→どういったものが使えるかは mdn string で検索
→String インスタンス

文字数を返す
`console.log(s.length);`

置換されたものを返す
`console.log(s.replace("t", "T"));`

添字の1から3文字分取って返す
`console.log(s.substr(1, 3));`

※注意

* var s = new String("taguchi");  文字列オブジェクト
* var s = "taguchi";  文字列リテラル

別物だが文字列リテラルにメソッドやプロパティをつけても同じ結果に変換される

## Arrayオブジェクトを使う

`<script>
　var a = new Array(100, 300, 200)
　// var a = [100, 300, 200];
　console.log(a.length); 
</script>`

配列の要素の個数を返す
`console.log(a.length);`

### 要素を追加する命令

* unshift：先頭に追加
* push：末尾に追加
* shift：先頭から除去
* pop：末尾から除去
* splice：途中で削除・追加

200の後に500を追加する
`<script>
　var a = new Array(100, 300, 200);
　a.push(500);
　console.log(a);
</script>`

300と200を削除し800と1000を追加する
`<script>
　var a = new Array(100, 300, 200);
　a.push(500);
　console.log(a);
　a.splice(1, 2, 800, 1000); 
　console.log(a);
</script>`
※第1引数に追加や削除の場所、第2引数に削除したい要素の数、第3引数から追加する要素
※pushによって500が最後に追加されている


## Math,Dateオブジェクトを使う
### Mathオブジェクト
他のオブジェクトと違ってnewする必要がない

円周率を表示する
`<script>
　console.log(Math.PI); //PIというプロパティにアクセスする
</script>`

メソッド

実数を切り上げする
`console.log(Math.ceil(5.3));`

実数を切り捨てする
`console.log(Math.floor(5.3));`

四捨五入する
`console.log(Math.round(5.3));`

0から1未満の実数のランダム値を生成する
`console.log(Math.random());`

### Dateオブジェクト
日付オブジェクト

現在時刻を取得
`<script>
　var d = new Date();
</script>`

ある特定の日付のものを取得（2月11日10時20分30秒）
`var d = new Date(2014, 1, 11, 10, 20, 30);`
※JavaScriptは月を0から数えるので、2月は1

現在時刻に対してメソッドを使い、年・月・基準日からの経過ミリ秒を取得
`<script>
　var d = new Date();
　console.log(d.getFullYear()); 
　console.log(d.getMonth());
　console.log(d.getTime()); // 1970/1/1から
</script>`


## windowオブジェクト
オブジェクトのプロパティを表示する
`console.dir(window); `

ブラウザの高さにアクセスする
`console.log(window.outerHeight);`

今見ているページから別のURLに飛ばす
`<script>
　window.location.href = 'http://dotinstall.com';
</script>`

<b>window.document ：今開いているページ</b>
※windowを省略しdocumentでもアクセス可能
<b>document object model (DOM) ：documentnにアクセスするための色々な命令</b>
※古いブラウザだと違う命令だったりする

### DOMを使って動的にページを書き換える
※DOMをいじるときはconsoleのElementsで見られるツリー構造を意識

```lang:html
<!DOCTYPE html>
<html lang="ja">
  <head>
      <meta charset="utf-8">
      <title>JavaScriptの練習</title>
      <style>
  .myStyle {
    font-weight: bold;
    border: 1px solid gray;
  }
      </style>
      </head>
  <body>
   <h1>見出し</h1>
   <p id="msg">こんにちは！</p> <!-- javascriptをいじるときはidをつける -->
  <script>
     var e = document.getElementById('msg');  //変数の中でidを取得
     e.textContent = 'Hello!'; //テキストを書き換える
     e.style.color = 'red'; //スタイルを変える
     e.className = 'myStyle'; //cssの適用
  </script>
</body>
</html>
```
### 要素を追加することが可能

body要素の中にp要素を追加して、そのp要素の中にtextを仕込む
→hello worldというテキストを作りたい
→createElement：greetというelementを作る
→createTextNode：textの追加
→appendChild：bodyに対して子要素を追加
 （追加したいのはgreetで、さらにtextを入れてあげる）

```lang:html
<!DOCTYPE html>
<html lang="ja">
  <head>
      <meta charset="utf-8">
      <title>JavaScriptの練習</title>
      <style>
  .myStyle {
    font-weight: bold;
    border: 1px solid gray;
  }
      </style>
      </head>
  <body>
   <h1>見出し</h1>
   <p id="msg">こんにちは！</p> <!-- javascriptをいじるときはidをつける -->
  <script>
    var greet = document.createElement('p'), //タグネームを指定
        text = document.createTextNode('hello world');
    document.body.appendChild(greet).appendChild(text); //bodyの子要素の一番最後に追加    
  </script>
</body>
</html>
```

###イベントを設定する
ページ内の要素にイベントを設定する

ボタンをクリックするごとにテキストを追加するイベント
→addEventListener：イベントを紐づける（第1引数にはイベントの種類、第2引数には関数を与える（今回はその場限りなので無名関数））

```lang:html
<!DOCTYPE html>
<html lang="ja">
  <head>
      <meta charset="utf-8">
      <title>JavaScriptの練習</title>
      <style>
  .myStyle {
    font-weight: bold;
    border: 1px solid gray;
  }
      </style>
      </head>
  <body>
   <h1>見出し</h1>
   <p id="msg">こんにちは！</p> 
   <button id="add">Click!</button>
  <script>
    document.getElementById('add').addEventListener('click' , function() {
    var greet = document.createElement('p'), 
        text = document.createTextNode('hello world');
    document.body.appendChild(greet).appendChild(text); 
        }); //idを取得→イベントを紐づける
  </script>
</body>
</html>
```