忘れがちなJavaScriptの基礎中の基礎


JavaScriptは他言語に比べて使用頻度が低い分、かるーい体系的なレファレンスがあればいいなと思ってまとめました。なお全ての使用可否判断は最新版chromeに依拠します。

_追記(0802)：JavaScriptをシンプルに記述できるCoffeeScriptに関する情報をまとめました。_
_-> 「[JavaScriptを卒業してCoffeeScriptで飛躍しよう - 基本などまとめ](http://qiita.com/Yama-to/items/a947cfa2565b03ddc9de)」_

## JSリファレンス

- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/ja/docs/Web/JavaScript)

## 記述場所

- `script`タグの中で記述
- 一般的にbodyタグの一番下にベタ書き
- ソースを記述することで別ファイル化も可能

```html:
<script src="index.js"></script>
```

## コメントアウト

- 単行コメントの場合

```js:
// コメント 
```

- 複行コメントの場合

```js:
/* 
コメント1
コメント2
コメント3
コメント4
*/
```

## 変数の定義

- 最初に変数の宣言が必要

```js:
var msg;
msg = "hello world"
```

- 宣言と定義を同時にかつ複数行うこともできる

```js
var ms1 = "hello world",
	ms2 = "ok, google.",
	ms3 = "g'day mate.";
```

**※JSの文末には必ず `;` を付与する**

## データ型
- 文字列
- 数値
	- 全て浮動小数点数
- 真偽値 
	- true
	- false
- オブジェクト
  - 配列
  - 関数
  - 組み込みオブジェクト
- undefined
	- 定義されていない存在
- null
	- 何もない無の存在

## 演算子
- 四則演算子
  - + (足し算)
  - - (引き算)
  - * (掛け算)
  - / (割り算)
  - % (剰余算)
- 代入演算子
  - +=
  - `x = x + 5` -> `x += 5`
- 単項演算子
  - ++ / --
  - `x++` -> xに1が足される

## 文字列の扱い
- 特殊文字はエスケープシーケンスを使用する

```html:
\n : 改行
\t : タブ
\' : シングルクオーテーション
\\ : バックスラッシュ
```

- 文字列と数値を演算すると文字列の合算になる

```js:
plus = "5" + 5;
// => "55"
```

## if文の扱い
- 通常の用法

```js:
if (条件1) {
	処理1
} else if (条件2) {
	処理2
} else {
	処理3
}

// 【例】
var score = 80;
if (score > 60) {
  console.log("ok!")
} else if (score > 40) {
  console.log("soso.")
} else {
  console.log("poor...")
}
```

- 三項演算子の用法

```js:
(条件) ? (true処理) : (false処理);

// 【例】
var score = 80;
x = (score > 60) ? "ok" : "poor";
console.log(x)
```

## データ型の真偽値

- 文字列
	- 空文字 (`null`) は **false**
- 数値
	- `0` か `NaN (Not a Number)` は **false**
- object
	- `undefined` か `null` は **false**

## switch文の扱い
- if文と同様の条件分岐を実現する
- 必ず各 `case` に `break` が必須となる
- if文の `else` にあたる `default` 条件分岐も必須

```js:
var signal = "blue";

switch (signal) {
    case "red":
        console.log("stop!");
        break;
    case "green", "blue":
        console.log("go!");
        break;
    case "yellow":
        console.log("slow down!");
        break;
    default:
        console.log("wrong signal");
        break;
}
```

## 2種類のwhile文の扱い
- 前置条件( `while構文` )
- 条件によっては一度も処理が実行されない

```js:
var i = 0;
while (i <= 10) {
    console.log(i);
    i++;
}
```
- 後置条件( `do-while構文` )
- 必ず処理を一度実行してから判定に入る

```js:
var i = 200;
do {
    console.log(i);
    i++;
} while (i < 10);
```

## for文の扱い
- 通常の繰り返し条件指定方法
	1. ループを回すための変数を初期化
	2. 繰り返し条件を指定
	3. 一度ループが回るごとに行う処理を記述

```js:
for (var i = 0; i < 10; i++) {
  console.log(i);
}
```

- `continue` を用いると指定条件下でループ処理をスキップする

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

// 0,1,2,3,4,6,7,8,9,10
```

- `break`を用いると指定条件に合致した際にループを中断する

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

// 0,1,2,3,4
```

## 基本的な3種類のポップアップ
1. alert
	- 引数に指定した文章と`OK`ボタンのみ表示される
	- 返り値は無し( `undefined` )

	```js:
	alert("hello");
	```
2. confirm
	- 引数に指定した文章と `OK` `キャンセル`ボタンが表示される
	- 返り値は、`OK`を選択した場合 `true`、`キャンセル` を選択した場合 `false` となる
	
	```js:
	confirm("are you sure?");
	```
3. prompt
	- 引数に指定した文書とテキスト入力欄を表示する
	- 返り値はユーザーが入力した値
	- 何も入力しなかった場合でも `undefined`にはならず空白として認識される
	- 第二引数にテキスト入力欄のデフォルト値を設定することも可能
	
	```js:
	prompt("input your name...", "anonymous");
	```

## 通常関数の使用
- 複数の処理のカタマリを関数という形でまとめることができる
- `function 関数名(引数) { 処理内容; return 返り値 };` が関数を定義するための基本構文
- スクリプト中に `関数名(引数)` と記述すれば作った関数を呼び出せる
- 返り値は変数に代入し、後に他所で利用することも可能

```js:
function hello(name) {
	return "hello " + name;
}

var hello_name = hello("Tom");
console.log(hello_name);
// => hello Tom
```

## 匿名関数の使用
- 先ほどの関数は以下のように定義した場合でも意味は同じ
- 関数自体に名前は命名しないため `無名関数` や `匿名関数` と呼ばれる手法

```js:
var hello = function(name) {
	var msg = "hello " + name;
	return msg;
}

var hello_name = hello("Bob");
console.log(hello_name);
// => hello Bob
```

**※関数内で定義した変数は `ローカル変数` と呼ばれ関数の外で使用できないことに注意**

## 即時関数の使用
- 関数の定義と実行を同時に行う構文
- 関数名は基本的に付与しない
- 再利用することもできない
- `(function (引数) { 処理内容 })(渡す引数);` が基本的な構文

```js:
(function (name) {
	var user = "Miss. " + name
	console.log(user)
})("Ann");

// => Miss. Ann
```

**※以下の理由から一時的なローカル変数が必要な際に使用することが多い**

1. 関数の外で変数を定義するとグローバルな変数としてスクリプト全体に影響を及ぼす
2. 任意の関数内で定義した変数はその関数内でのみ使用可能なローカル変数となる
3. ローカル変数を使用することにより意図しないグローバル変数の上書きなどが発生しない
3. 上記の例だと `user` という変数が関数外で既に使用されていたとしても関数の実行によって上書きはされない

## 時間差で処理を行う3つの方法
1. setInterval
	- 第一引数に関数、第二引数に周期(ミリ秒)を設定し同一の処理を同一間隔で繰り返す
	- `setInterval( 関数, ミリ秒周期 )` というのが基本的な構文
	- ループ処理自身を変数に格納し `clearInterval` を指定することで処理を中断できる
	
	```js:
	var i = 0;
	function show() {
		console.log(i++);
		if (i > 3) {
			clearInterval(timer);
		}
	}
	var timer = setInterval(show, 1000);
	
	// => 0,1,2,3...
	```
2. setTimeout
	- 第一引数に関数、第二引数に時間(ミリ秒)を設定し指定の処理を指定時間経過後に一度実行する
	- `setTimeout( 関数, ミリ秒時間 )` というのが基本的な構文
	
	```js:
	var i = 0;
	function show() {
		console.log(i++);
	}
	setTimeout(show, 1000);
	
	// => 0
	```
3. setTimeout(ループ処理)
	- `setTimeout` を用いて `setInterval` のようにループ処理を行うこともできる
	- 1つの関数内に `setTimeout` を設置し一定時間を置いて再度その関数自身を読み込むよう記述する
	- ループ処理自身を変数に格納し `clearTimeout` を指定することで処理を中断できる
	
	```js:
	function show() {
	  console.log(i++);
	  var timer = setTimeout(show, 1000);
	  if (i > 3) {
	    clearTimeout(timer);
  	  }
	}
	show();
	
	// => 0,1,2,3...
	```

**※上記2種類のループ処理は以下の点で異なる**

- `setInterval` は直前の処理が完了したかを判定せずに次の操作を行う
-  `setTimeout` は直前の操作の完了を待って次の処理を行う
- そのために各回の処理が重い場合には `setInterval` メソッドを使用しているとブラウザが落ちてしまう場合がある

## 配列とオブジェクト
- 配列
	- 順番で管理された複数の情報のカタマリ
	- 配列のインデックス番号を指定して値を呼び出すことや上書きすることも可能

	```js:
	var foods = ["potato", "banana", "coffee"];
	
	console.log(foods[0]); // => potato
	foods[0] = "melon";
	console.log(foods) // => ["melon", "banana", "coffee"];
	```
- オブジェクト
	- 名前と値の組み合わせを複数持った情報のカタマリ
	- `名前: 値` という形で記録していく
	- それぞれの値は `プロパティ` と言われ、呼び出しや上書きも容易にできる
	- 各値を参照する方法は `オブジェクト名.プロパティ名` と `オブジェクト名["プロパティ名"]` の2種類存在する
	
	```js:
	var food = {
	  name: "tomato",
	  calory: 120,
	  color: "red",
	  taste: "sour"
	};
	
	console.log(food.name); // => tomato
	console.log(food["calory"]); // => 120
	food.color = "yellow";
	console.log(food); // => Object {name: "tomato", 	calory: 120, color: "yellow", taste: "sour"}
	```

## オブジェクトの扱い
- オブジェクトのプロパティには関数を指定できる
- プロパティに設定した関数を、オブジェクトの `メソッド` という
- メソッド内で `this` を用いると、そのメソッドを包括しているオブジェクト自身を指すことができる

```js:
var user = {
  email: "sample@gmail.com",
  address: "Shibuya",
  contact: function (name) {
    console.log("hello " + name + " from " + this.email);
  }
};

user.contact("yam")
// => hello yam from sample@gmail.com
```
**※`console.dir(オブジェクト名)` としてもそのオブジェクト自身が持つプロパティを表示できる**

## 組み込みオブジェクト
- 予めJavaScriptが用意しているオブジェクトが存在する
- 各オブジェクトは予めプロパティやメソッドを持っている
- それらを調べるには[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference)の該当セクション内「〇〇インスタンス」の項を参照する
- 新しいオブジェクトは `var 変数 = new オブジェクト名(セットする値)` という形で生成する
- 単に `var 変数 = セットする値` とすると、オブジェクトと性質が似通う `リテラル` を生成できる

1. Stringオブジェクト（文字列）
	- lengthプロパティ
		- 文字列の長さを返す
		
		```js:
		var s = new String("poteto");
		console.log(s.length);
		// => 6
		```
	- replaceメソッド
		- 指定した一文字を入れ替える
		- 第一引数に入れ替える対象、第二引数に挿入する文字列を指定する
		
		```js:
		var s = new String("poteto");
		console.log(s.replace("t", "tak"));
		// => potaketo
		```
	- substrメソッド
		- 指定した範囲の文字列を取得する
		- 第一引数に開始位置、第二引数に長さを指定する
		
		```js:
		var s = new String("poteto");
		console.log(s.substr(2, 3));
		// => tet
		```

2. Arrayオブジェクト（配列）
	- shift / unshift メソッド
		- 配列の先頭の要素を削除/追加する
		
		```js:
		var a = ["banana", "apple", "orange"]
		
		a.shift()
		console.log(a) // => ["apple", "orange"]
		a.unshift("peach")
		console.log(a) // => ["peach", "apple", "orange"]
		```
	- pop / push メソッド
		- 配列の末尾の要素を削除/追加する
		
		```js:
		var a = ["banana", "apple", "orange"];
		
		a.pop();
		console.log(a); // => ["banana", "apple"]
		a.push("grape");
		console.log(a); // => ["banana", "apple", "grape"]
		```
	- spliceメソッド
		- 指定した範囲の要素を入れ替える
		- 第一引数に開始位置、第二引数に長さ、第三引数以降に代入する要素を指定する
		
		```js:
		var a = ["banana", "apple", "orange"];
		
		a.splice(0, 2, "cherry", "pineapple", "berry");
		console.log(a); // => ["cherry", "pineapple", "berry", "orange"]
		```
_(追記：「第一引数の文字列を第二引数の文字列で置き換える」が正確な説明のようです。第一引数に正規表現オブジェクトを指定した場合、マッチするもの全てを置き換えることも可能です。)_

3. Mathオブジェクト（数学的計算）
	- ceilメソッド
		- 指定した数値の小数点を切り上げた値を返り値とする
		
		```js:
		console.log(Math.ceil(5.2));
		// => 6
		```
	- floorメソッド
		- 指定した値の小数点を切り下げた値を返り値とする
		
		```js:
		console.log(Math.floor(7.8));
		// => 7
		```
	- roundメソッド
		- 指定した数値の小数点以下四捨五入した値を返り値とする
		
		```js:
		console.log(Math.round(3.6));
		// => 4
		```
4. Dateオブジェクト（日付情報）
	- 現在の時刻情報を持ったオブジェクト生成
	
		```js:
		var d = new Date();
		console.log(d);
		// => Wed Jun 10 2015 03:27:27 GMT+0900 (JST)
		```
	- 指定日時の時刻情報を持ったオブジェクト生成
		**※月の指定は0~11の範囲で行い、1ずつ値がズレることに注意**
	
		```js:
		var d = new Date(2015, 6, 12, 3, 24, 56);
		console.log(d)
		// => Sun Jul 12 2015 03:24:56 GMT+0900 (JST)
		```
	- 生成したDateオブジェクトから西暦年や月の情報だけ抽出
		- `getFullYear` メソッドは年の値を返す
		- `getMonth` メソッドは月の値を返す
		- `getTime`メソッドは `1970年1月1日からの経過ミリ秒` を取得する
		
		```js:
		var d = new Date(2015, 5, 10, 3,24,56);
		
		console.log(d.getFullYear()); // => 2015
		console.log(d.getMonth()); // => 5
		console.log(d.getTime());  // => 1433874296000
		```
		
## windowオブジェクト
- ファイルを表示しているブラウザ自身を `windowオブジェクト` として扱うことができる
	-  outerHeightプロパティ
		- ブラウザの高さを取得できる
		
		```js:
		console.log(window.outerHeight);
		// => 974
		```
	- locationプロパティ
		- href属性の指定と併用することでリダイレクトを行う
		
		```js:
		window.location.href = 'http://google.com';
		// => Googleにリダイレクト
		```
	- documentプロパティ
		- 今開いているページを指す
		- `window.` を省略可能
		
		```js:
		console.log(window.document)
		console.log(document)
		```

## DOM (Document Object Model)
- documentプロパティにアクセスするための様々な命令を表す
- 以下は使用例

```html:
<!DOCTYPE HTML>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>JS-practice</title>
  <style type="text/css">
    .sampleStyle {
      font-weight: bold;
      text-decoration: underline;
    }
  </style>
</head>
<body>
  <p id="msg">hello world</p>
  <script>
	var ele = document.getElementById('msg'); // ①
	ele.textContent = 'good-bye world'; // ②
	ele.style.color = 'blue'; // ③
	ele.className = 'sampleStyle'; // ④
	
	var pgp = document.createElement('p'), // ⑤
		txt = document.createTextNode('good-morning world'); // ⑥
	document.body.appendChild(pgp).appendChild(txt); // ⑦
  </script>
</body>
</html>
```
1. `document.getElementById` メソッド
	- HTML中の要素をID指定で取得する
	- 取得した際に変数に格納しておくと後の処理で使用できる
2. `textContent` プロパティ
	- 指定の要素が包括する文字列を取得する
	- 取得するだけでなく上書きすることも可能
3. `style` プロパティ
	- 指定の要素に対して様々なスタイルを指定できる
	- 上記では文字列の色を変更している
4. `className` プロパティ
	- 指定の要素のclass属性を取得する
	- 上記ではclassを新規指定することで予め用意してあったスタイルが要素に当たるようにしている

5. `document.createElement` メソッド
	- 新たな要素を新規生成する
	- 引数に生成したい要素のタグを指定する
	- 生成した要素を変数に格納することで種々の指定が行い易くなる
6. `document.createTextNode` メソッド
	- テキストの情報を新規生成する
	- 存在するタグに組み込んだりして使用できる
	- 生成したテキスト情報を変数に格納することで後の処理が行い易くなる
7. `appendChild` メソッド
	- メソッドを呼び出す要素の配下に、引数で渡した要素を追加する
	- 上記だとbodyタグ内に、生成したp要素を追加している

## 特定のイベントに連動した動作の設定
- `document.getElementById`メソッドで取得した要素には特定のイベントを行った時の挙動を指定できる
- イベントと挙動の指定を行うには `addEventListener` メソッドを使用する
- `要素.addEventListener('イベント', 関数)` という形が基本的な構文
- 以下は、PopUp!ボタンの[OK]を選択し続けた場合のみ「1Tap!」が増えていく実装例

```html:
<!DOCTYPE HTML>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>JS-practice</title>
</head>
<body>
  <p id="ary">[Taps] </p>
  <button id="btn">PopUp!</button>
  <script>
  	// イベントを設定する対象の指定
	var btn = document.getElementById('btn');
	// ボタンをクリックした時に行う動作の指定
	btn.addEventListener('click', function () {
	  // ポップアップを表示
  	  var pop = confirm('add text to ary?');
  	  // 実際に変更を加えるための要素の取得と生成
  	  var ary = document.getElementById('ary');
  	  var txt = document.createTextNode("1tap! / ");
  	  // ポップアップで選択した値によって動作を変える
  	  if (pop == true) {
  	    ary.appendChild(txt);
	  } else {
	    ary.textContent = "[Taps] ";
  	  }
	});
  </script>
</body>
</html>
```
**※他に指定可能なイベントは[W3SCHOOL](http://www.w3schools.com/jsref/met_document_addeventlistener.asp)のサイトが参考になる**

---

以上、JavaScriptの基礎中の基礎をまとめて備忘録とします。