JavaScript 基礎

ドットインストールの「JavaScript 入門」を履修したのでメモを残しておく。
# 関数について

## 関数の型
関数もデータ型なので変数に格納することが可能。

``` js:
var greet = function greet(name) {
...
}
```

変数に格納する場合は関数名は必要ない。名前を持たない関数は **「無名関数」** **「匿名関数」** と呼ぶ。
無名関数は式そのものになるので、最後はセミコロンをつける必要がある。

```js:
var greet = function(name) {
    var word = "hello " + name;
    return word;      
};                 
var msg = greet("Bob");
console.log(msg);
```
## 即時関数
定義した関数をすぐ使用したい時には以下のように（）でくくり、引数を設定する。

```js:
(function(name) {
    console.log("hello " + name);
})("Bob");
```
関数名は省略することが可能。
この即時関数は自分が定義した変数を他の人が書いたプログラムからの影響を受けず、かつ他の人が書いたプログラムに影響を与えない**ローカル変数**に設定する時にも使用される。

```js:
(function() {
    var x = 100,
        y = 200;
    console.log(x + y);
})();
```

ここでは ```x``` と ```y``` がローカル変数となる。

# タイマー処理について
ここで説明するタイマー処理は以下の2つ。
```setInterval``` : 一定時間ごとにある処理を行う
```setTimeout``` : 一定時間経過したのちにある処理を一回だけ行う

```js:タイマー処理を使用した例
var i = 0;
function present() {
    console.log(i++);
}
// 第1引数：行う処理　第2引数：時間（ミリ秒）
setInterval(function() {
    present();
}, 1000);
```

```setTimeout``` も同じ引数をとる。一見繰り返し処理には ```setInterval``` が有効であると思われるが、 ```setInterval``` は前の処理が終了したかどうかを確認せずに次の処理が実行されるため、重い処理が行われる場合はブラウザがクラッシュしてしまう。一方で ```setTimeout``` は前の処理が終了した後に次の処理が行われるため、繰り返し処理には ```setTimeout``` がよく用いられる。

```js:setTimeoutを使用した繰り返し処理
var i = 0;
function present() {
    console.log(i++);
    var tid = setTimeout(function() {
        present();
    }, 1000);

    // 任意の条件でタイマー処理を終了させる
    if (i > 4) {
        clearTimeout(tid);
    }
}
present();
```
# 配列
```js:
//　基本形
var score = [100, 200, 300];
// 配列アクセス
console.log(score[0]); // 100
// 代入
score[1] = 400;
// １つの配列に異なるデータ型を代入可能
var score = [100, 200, "hoge"];
// 入れ子構造にもできる
var score = [
    [1, 2, 3],
    [4, 5, 6],
];
// アクセス
console.log(score[1][1]); // 5

```

# オブジェクト
配列と同じく変数の集合を扱うときに利用。名前と値のセットで定義する（この組をプロパティと呼ぶ）。

```js:オブジェクト定義
var user = {
    email: "hoge@gmail.co.jp"
    score: 20
};
```

この場合```email```や```score```は**「プロパティ名」**と呼ばれる。プロパティ名はダブルクォーテーションで括っても良いが、括らなくても問題ない。

```js:アクセスと代入
// アクセス
console.log(user["email"]);
console.log(user.email);

// 代入
user.score = 100;
```
オブジェクトはプロパティの値に関数を持つことも可能。オブジェクト内の関数のことをオブジェクトの**メソッド**と呼ぶ。

```js:メソッドを持ったオブジェクト
var user = {
    email: "hoge@gmail.co.jp"
    score: 20
    greet: function(name) {
        console.log("Hi, " + name);
    }
};
// メソッド呼び出し
user.greet("Bob");

```
Javaと同様に```this```を用いてオブジェクトのプロパティの値を参照することが可能。

```js:メソッドを持ったオブジェクト
var user = {
    email: "hoge@gmail.co.jp"
    score: 20
    greet: function(name) {
        console.log("Hi, " + name + " from " + this.email);
    }
};
// メソッド呼び出し
user.greet("Bob");

```
自身で設定したオブジェクトに加えてJavaScriptはあらかじめ使用できる**組み込みオブジェクト**が存在する。以下は組み込みオブジェクトの例

* String
* Array
* Math
* Date

どんなプロパティが使用できるかはリファレンスを参照すると良い。

### String オブジェクト

```js:例
var s = new String("hoge");
// 文字列の長さ
console.log(s.length);
// 文字列の置換
console.log(s.replace("h","H"));
// 部分文字列を取得
console.log(s.substr(1,3)); // oge が出力
```
文字列オブジェクトであるStringオブジェクトとは別に**文字列リテラル**が存在する。文字列リテラルは厳密にはStringオブジェクトとは別物だが、Stringオブジェクトのような使用をするとJavaScript側で勝手にStringオブジェクトだと認識してくれる。

```js:文字列リテラル
var s = "hoge";
console.log(s.length);
console.log(s.replace("h","H"));
console.log(s.substr(1,3));
```

### Array オブジェクト
```js:
var a = new Array(100, 200, 300, 400);
// 要素数
console.log(a.length);

// 要素の追加、削除[先頭、末尾]
// 追加： unshift -> array <- push
// 削除： shift <- array -> pop
a.push(500);

// 要素の追加、削除[途中]
a.splice(/*削除する配列のインデックス*/ 1,
         /*削除する要素の個数*/ 2,
         /*追加する要素*/ 100, 200, ...);
```
### Math オブジェクト
```js: 
// 円周率
console.log(Math.PI);
// 切り上げ
console.log(Math.ceil(2.3));
// 切り捨て
console.log(Math.floor(2.3));
// 四捨五入
console.log(Math.round(2.3));
// 乱数
console.log(Math.random());
```

### Date オブジェクト

```js:
// 現在の日付、時刻を取得
var d = new Date();

// 特定の日付、時刻を設定
var d = new Date( /* year */ 2014,
                  /* Month */ 1, // 月は0始まりなのでここでは「２月」
                  /* Day */ 11,
                  /* Hour */ 10,
                  /* Minutes */ 20,
                  /* Seconds */ 30);
// 年を取得
console.log(d.getFullYear());
// 月を取得
console.log(d.getMonth());
// 1970/1/1 からの経過ミリ秒
console.log(d.getTime()); 
```

### Window オブジェクト
ブラウザ自体もオブジェクトなのでJavaScript側から設定変更を行うことが可能となる。

```js:
// Window の高さ
console.log(window.outerHeight);
// ページ遷移
window.location.href = "http://hoge.com"
```
Window オブジェクトでもっとも使用するのが```window.document```である。これは今開いているページを編集する(DOM をいじる)ときに使われる。単に```document```と省略することも可能。

```html:
<body>
    <h1> Title </h1>
    <p id="msg"> Hello! </p>
    <script>
        var e = document.getElementById('msg');
        e.textContent = 'hello!';
        e.style.color = 'red';
        // CSS 指定
        e.className = 'myStyle'; 
        // 要素追加
        var greet = document.createElement('p'),
            text = document.createTextNode('hello world');
        document.body.appendChild(greet).appendChild(text);
    </script>
</body>
```

# イベントを設定する

### ボタンを設置

ボタンをクリックした時の処理を定義するには```addEventLister```メソッドを使用。

```html:
<body>
    <h1> Title </h1>
    <p id="msg"> Hello! </p>
    <button id="add"> Please click </button>
    <script>
        var e = document.getElementById('msg');
        e.textContent = 'hello!';
        e.style.color = 'red';
        // CSS 指定
        e.className = 'myStyle'; 
        
        // ボタンクリック時の処理
        document.getElementById('add').addEventLister('click', function(){
            var greet = document.createElement('p'),
            text = document.createTextNode('hello world');
            document.body.appendChild(greet).appendChild(text);
        });
    </script>
</body>
```
これによりボタンがクリックされる度にテキストが追加される。