JavaScript本格入門(改訂新版)読書録①

## 概要

個人的なJavaScript本格入門(改訂新版)の読書録①
[改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X/ref=sr_1_1?ie=UTF8&qid=1514698028&sr=8-1&keywords=javascript+%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80
)

## 導入部分

### JavaScriptとは？

Netscape Communications社によって開発された、ブラウザー向けのスクリプト言語。
開発当初はLiveScriptと呼ばれていたが、当時注目を浴びていたJavaにあやかってJavaScriptと名前を改めた。
なお、JavaとJavaScriptの間には、言語仕様に似た部分はあるものの、全くの別言語であり、互換性もない。

### 特徴

- script言語である

スクリプト言語とは、簡易であることを目的として作られたプログラミング言語のこと。
またオブジェクト指向的な構造も持ち合わせているので、再利用性、保守性を担保したコードも書きやすい。

- インタプリタ型の言語である

インタプリタ言語とは、プログラムを先頭から逐一解析し、コンピュータに理解できる形式に翻訳しながら実行していく言語のこと。
コンパイルする前にソースコードをオブジェクトコードに翻訳しておいてから実行するコンパイル言語に比べると動作が遅い問題はあるが、プログラムを実行するためにコンパイルのような特別な手続きが必要ないというメリットがある。

- 様々な環境で利用できる
- いくつかの機能から構成される

### 開発者ツールについて

#### 開発者ツールを起動する

主なブラウザで開発者ツールを起動する方法は下記の通り。

|ブラウザー|起動方法|
|---|---|
|Google Chrome|[Google Chromeの設定] - [その他ツール] - [デベロッパーツール]|
|Microsoft Edge|[詳細] - [F12開発者ツール]|
|Internet Explorer|[ツール] - [F12開発者ツール]|
|Firefox|[メニューを開きます] - [開発者ツール] - [開発ツールを表示]|
|Opera|[メニュー]　- [開発者] - [開発者用ツール]|
|Safari|[開発] - [Webインスペクタを表示]|

Google Chromeでの開発者ツールのメニュー一覧は下記。

|メニュー|概要|効果|
|---|---|---|
|*Elements|HTML/CSSの状態を確認|スクリプトの実行結果を確認する際に有効|
|*Network|ブラウザで発生した通信を走査|特にAjaxによって発生した非同期通信は表に現れにくいが、このタブで正しいリクエストがなされているか、意図したデータを受信できているか、確認しやすくなる。|
|*Sources|スクリプトのデバッグ(ブレイクポイントの設置、変数の監視など)|コード左の行番号をクリックすることで、ブレイクポイントを設定でき、デバッグが可能になる。|
|Timeline|パフォーマンスを計測||
|Profiles|JavaScriptで使用しているCPU/メモリなどの情報を収集||
|*Application|Cookie/ストレージなどの内容を確認|現在のページを構成するファイルのほか、ストレージ、クッキーを確認できる。また、リストから値を追加/編集/削除することも可能。|
|Audits|ページを分析し、最適化のためのヒントをリスト表示||
|*Console|コンソール(変数情報の確認、エラーメッセージの表示など)|エラーメッセージやログを確認できる。また対話的にJavaScriptのコードを実行できる。|

また、ダウンロード時間節約のため、レスポンスに際してコードが圧縮された状態で読みづらくなっていることがあるが、そのような時は[Sources]タブ下の `{}` (Pretty Print) ボタンをクリックすることで、コードを改行/インデント付きの読みやすい形式に変えることができる。

## 基本的な書き方について

### script要素について

script要素は、JavaScriptのコードをHTMLに組み込む役割をもつ。
type属性はスクリプトの種類を表す。一般的には「text/javascript」以外を指定することはない。(HTML5では、そもそも「text/javascript」がデフォルト値となっているため省略しても問題ない。)

script要素を記述する場所については、状況に応じてbody要素の配下またはhead要素の配下に記述する。
JavaScriptでは「関数を呼び出すための`script`要素より、関数定義の`script`要素を先に記述しなければいけない」というルールがあるため。
(例えば、`body`要素の配下で呼び出す必要があるような関数は、`head`要素の配下で事前に読み込んでおく必要がある。)

### 外部スクリプトのインポート

JavaScriptのコードは、外部ファイルとして別に定義することもできる。

```hello_ex.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JavaScript本格入門</title>
</head>
<body>
<script type="text/javascript", src="hello_ex.js">
</script>
<noscript>JavaScriptが利用できません。</noscript>
</body>
</html>
```

```hello_ex.js
window.alert('こんにちは、世界！');
```

コードの外部化には

- レイアウトとスクリプトを分けることで、コードを再利用しやすくなる
- スクリプトを外部化することで、.htmlファイルの見通しがよくなる

といったメリットがあり、本格的なアプリ開発では、可能な限りJavaScriptは外部ファイル化したほうがいい。

### 外部スクリプトとインラインスクリプトの注意点

外部スクリプトとインラインスクリプトを併用する場合、以下のような記述はできない。
src属性を指定した場合、script要素配下のコンテンツは無視されるため。

```example.js
<script type="text/javascript", src="hello_ex.js">
window.alert('こんにちは、世界！'); // 無視される
</script>
```

もし外部スクリプトとインラインスクリプトを併用する場合は、以下のようにscript要素も別にしなければならない。

```example.js
<script type="text/javascript", src="hello_ex.js"></script>
<script type="text/javascript">
window.alert('こんにちは、世界！');
</script>
```

### アンカータグにスクリプトを埋め込む

script要素での記述のほか、アンカータグのhref属性に、「JavaScript: ~」の形式でスクリプトを埋め込むことができる。このような記法を「JavaScript擬似プロトコル」という。

```
<a href="JavaScript:スクリプトコード">リンクテキスト</a>
```

例えば「リンクをクリックした時にダイアログを開きたい」という場合、以下のように書く。

```protocol.html
<a href="JavaScript:window.alert('こんにちは、世界！');">ダイアログを表示</a>
```

### コメントを挿入する

コメント記述には、下記3つの記法がある。

|記法|概要|
|---|---|
|// comment|単一行コメント。「//」から行末までをコメントとみなす。|
|/* comment */|複数行コメント。「/*~*/で囲まれたブロックをコメントとみなす|
|/** comment */|ドキュメンテーションコメント。/**~*/で囲まれたブロックをコメントとみなす|

### 変数

javascriptには、下記2種類の変数宣言方法があり、違いは2つ。

```
var num = 1
let num = 1
```

var・・・同名の変数宣言を許可しない。
let・・・同名の変数宣言を許可する。ブロックスコープを認識するため、より細かく変数の有効範囲を管理できる。

以上から、ES2015を利用できる環境では、できるだけlet命令を優先して利用したほうがいい。

### 識別子

識別子：スクリプトを構成する要素につけられた名前のこと。
変数だけでなく、関数やメソッド、ラベル、クラスなどは全て互いを識別するため、何らかの名前を持っている。
基本的に自由に設定できるが、4つの命名規則があることに注意する。

|NO.|規則|良い例|悪い例|
|---|---|---|---|
|1|1文字目は、英字/アンダースコア/ドル記号のいずれかであること|_name, $msg|1x|
|2|２文字目以降は、１文字目で使える文字、もしくは数字のいずれかであること|msg1, _name0|c@c, name-0|
|3|変数名に含まれる英字の大文字/小文字は区別される|name, Name|-|
|4|JavaScriptで意味を持つ予約語でないこと|tiff, forth|for, if|

なおJavaScriptでの予約語は以下の通り。
https://msdn.microsoft.com/ja-jp/library/0779sbks(v=vs.94).aspx

### 定数

定数宣言には、var/let の代わりに　const 命令を利用する。

```
const 定数名 = 値
```

定数の命名規則は、定数であることを識別しやすいよう、全てを大文字で、単語をアンダースコアで区切るのが一般的。
ex) CONSUMPTION_TAX, USER_NAME

### データ型

Javascriptで扱える主なデータ型は下記の通り。
大きく「基本型」「参照型」があり、違いは「値を変数に格納する方法」。
基本型の変数には、値そのものが直接格納されるのに対し、参照型の変数には、その参照値(値を実際に格納しているメモリ上のアドレス)が格納される。

|分類|データ型|概要|
|---|---|---|
|基本型|数値型|数値|
|基本型|文字列型|シングル/ダブルクオートで囲まれた0個以上の文字の集合|
|基本型|真偽型|true(真)/false(偽)|
|基本型|シンボル型|シンボルを表す|
|基本型|特殊型|値が空、未定義であることを示す|
|参照型|配列|データの集合(各要素にはインデックス番号でアクセス可能)|
|参照型|オブジェクト|データの集合(各要素には名前でアクセス可能)|
|参照型|関数|一連の処理(手続き)の集合|

### エスケープ文字

文字列リテラルでは、特別な意味を持つ文字(キーボードから直接に表現できない文字など)を「\ + 文字」という形式で表現できる。このような文字のことをエスケープシーケンスという。JavaScriptで利用可能なエスケープシーケンスには、以下のようなものがある。
※リテラル：データ型に格納できる値そのもの、また値の表現方法のこと。

|文字|概要|
|---|---|
|\b|バックスペース|
|\ƒ|改ページ|
|\n|改行|
|\r|復帰|
|\t|タブ文字|
|\\|バックスラッシュ|
|\'|シングルクオート|
|\"|ダブルクオート|
|\xXX|Latin-1文字。ex) \x61 (a)|
|\uXXXX|Unicode文字。ex) \u3042 (あ)|
|\u{XXXXX}|0xffff(4桁の16進数)を超えるUnicode文字。ex) \u{20b9f} (叱)|

エスケープ文字使用時にはいくつか注意点があり、例えばシングルクオートで囲まれた文字列にシングルクオートを含めることはできないが、上記のエスケープ文字を使うと、それが可能になる。

```
console.log('He\'s Hero!!');
```

このように、ある文脈の中である意味を持つ文字を、あるルールに基づいて無効化することをエスケープ処理という。

### テンプレート文字列

テンプレート文字列を使うことで、

- 文字列への変数の埋め込み
- 複数行にまたがる(改行文字を含んだ)文字列

といった文字列表現が可能になる。
テンプレート文字列では、シングルクオート/ダブルクオートの代わりに「`」(バッククオート)で文字列をくくる。

```template.js
let name = '鈴木'
let str = `こんにちは、${name}さん。
今日もいい天気ですね！`;
console.log(str)

// 出力結果↓

// こんにちは、鈴木さん。
// 今日もいい天気ですね！
```

### 未定義値

未定義値(undefined)は、ある変数の値が定義されていないことを表す値で、以下のようなケースで返される。

- ある変数が宣言済みであるものの、値が与えられていない
- 未定義のプロパティを参照しようとした
- 関数で値が返されなかった

```example.js
var x;
var obj = {a:12345}
console.log(x) // 結果：undefined (値が設定されていない)
console.log(obj.b)　// 結果：undefined (値が設定されていない)
```

### 例外処理

「引数に予期せぬ値が渡された」「関数やクラスを意図せぬ方法で利用された」など、呼び出し側に起因するエラーが起こった場合でも、スクリプト全体が停止しないようにする役割がある。これを実現するのは、try...catch...finally命令。

```example.js
var i = 1;
try {
  i = i * j; // 例外発生
} cache {
  console.log(e.message);
} finally {
  console.log('処理は完了しました');
}

// 出力結果

// j is not defined
// 処理は完了しました
```

なお例外処理は、確実に動作するスクリプトを記述する上で欠かせない仕組みだが、オーバーヘッドの大きい処理でもある。そのため例えば、ループ処理の中でtry...catchブロックを記述することは避けるべきで、ループ処理の外に配置できないかを検討する。

また例外の原因に応じて、Errorオブジェクトの代わりに、以下のXxxxxErrorオブジェクトを利用することもできる。

|オブジェクト|エラーの原因|
|---|---|
|EvalError|不正なeval関数|
|RangeError|指定された値が許容範囲を超えている|
|ReferenceError|宣言されていない変数にアクセスした|
|SyataxError|文法エラー|
|TypeError|指定された値が期待されたデータ型でない|
|URIError|不正なURI|