Suzuki Blog Written by Yuki Suzuki

【JavaScript本格入門】読書メモ

JavaScript 読書

『JavaScript本格入門』を読んだ際の、読書メモです。

スポンサードサーチ

メモ

Chapter1

・JavaScriptの特徴

  • スクリプト言語である
  • インタプリター型の言語である
  • さまざまな環境で利用できる(Node.jsなど)
  • いくつかの機能から構成される(DOM、ブラウザーオブジェクトなど)

・ECMAScript
標準化団体ECMA Internationalによって標準化されたJavaScript
class命令の導入など、大きな変革があった

・トランスコンパイラー
ES2015のコードを従来のES5仕様のコードに変換するツール
「Babel」など

Chapter2

・JavaScriptのコードは、1つ以上の文から構成される。以下のルールがある。

  • 文の末尾にセミコロンを付ける
  • 文の途中で空白は改行、タブを含めることも可能
  • 大文字小文字が厳密に区別される

・変数の宣言
変数の名前をJavaScriptに登録し、かつ、値を格納するための領域をメモリ上に確保すること
var命令よりもlet命令を優先して利用する

・識別子
スクリプトを構成する要素に付けられた名前のこと(変数、関数など)
様々な命名規則や、読みやすいコードを書くための留意点がある

・定数
途中で中身を変更できない値。意味ある値にあらかじめ名前をつける仕組みとも言える。マジックナンバーの記述を避けることができる。const命令で宣言できる。

・データ型
データの種類。文字列型、数値型、真偽型など。
プログラミング言語には、データ型を強く意識するものと、ほとんど意識しないものがある
JavaScriptは後者
JavaScriptの変数は、基本型と参照型に分類できる。違いは「値を変数に格納する方法」
基本型の変数には、値そのものを直接格納される
参照型の変数には、その参照値(値を格納しているメモリ上のアドレス)が格納される

・リテラル
データ型に格納できる値そのもの

・配列
データの集合。複数の値を管理可能。
個々のデータを「要素」と呼ぶ。

・オブジェクト
名前をキーにアクセスできる配列。ハッシュ、連想配列などと呼ばれる場合もある。
個々のデータを「プロパティ」と呼ぶ。

・それぞれの演算子には優先順位がある

・結合則
優先順位が等しい場合にどの方向に演算を行うかを決めるルール

・プログラミングの構造は大きく3つに分類できる

  1. 記述された順番に処理を行っていく順次
  2. 条件によって処理を分岐する選択
  3. 特定の処理を繰り返し実行する反復

これらを組み合わせてプログラムを組み立てる手法を構造化プログラミングといい、JavaScriptでも例外ではない

・処理を分岐するための命令として、if命令、switch命令がある

・条件分岐と並んで、よく利用される繰り返し処理として、for命令などがある

・try…catch…finally命令
例外処理を実現する
例外処理…「数値を受け取ることを想定した関数に文字列が渡された」など

Chapter3

・オブジェクト指向
プログラム上で扱う対象をオブジェクト(モノ)に見立て、オブジェクトを中心にコードを組み立てる手法
オブジェクトはプロパティとメソッドから構成される

・プロパティ
オブジェクトの状態や特性を表すための情報

・メソッド
オブジェクトを操作するための道具

・例:フォームを表すFormオブジェクト
プロパティ→フォームの名前、送信先URL…
メソッド→フォームを送信する、フォームをクリアする…

・オブジェクトは直接操作せず、複製したコピーを操作する
オブジェクトを複製すること→インスタンス化
インスタンス化によってできた複製のこと→インスタンス
インスタンス化するにはnew演算子を利用する

・組み込みオブジェクト
JavaScriptに標準で組み込まれたオブジェクト

・Stringオブジェクト
文字列型を扱うためのオブジェクト

・Numberオブジェクト
数値型を扱うためのオブジェクト

・Symbolオブジェクト
シンボルを作成できる
シンボルは一意であるため、列挙定数、プライベートプロパティ、イテレーターを定義するのに利用できる

・Mathオブジェクト
数学演算の機能を提供する

・Arrayオブジェクト
配列型の値を扱うためのオブジェクト
配列に対して要素の追加、削除、結合、並べ替えなどを行う機能を提供する

・配列を生成する際には、コンストラクター経由ではなく、配列リテラルを使用するべき

// コンストラクター経由
let ary = new Array(10);

// 配列リテラル
let ary = [];

コンストラクター経由だと、意味的にあいまいになりやすい

上記は「10という要素を持った配列」ではなく、「長さが10の配列」と認識される

・スタック
後入れ先出し、または先入れ後出しと呼ばれるデータ構造
push/popメソッドで実装できる

・キュー
先入れ先出しと呼ばれるデータ構造
push/shiftメソッドで実装できる

・Mapオブジェクト
連想配列を管理するためのオブジェクト

・Setオブジェクト
重複しない値の集合を管理するためのオブジェクト

・Dateオブジェクト
日付を表現、操作できる
リテラル表現は存在しないため、コンストラクターを経由する必要がある

let d = new Date();

・RegExpオブジェクト
正規表現を解析し、文字列検索するための機能を提供する

・正規表現
あいまいな文字列パターンを検索できる仕組み
例:郵便番号のパターン=「0~9の数値3桁」+「-」+「0~9の数値4桁」
正規表現にすると、[0-9]{3}-[0-9]{4}

・Objectオブジェクト
他のオブジェクトに対して、「オブジェクトの共通的な性質、機能を提供」する

・JSON
JavaScriptのオブジェクトリテラル形式に準じたデータフォーマット
JavaScriptとは親和性が高く、Ajax通信などではよく利用されている
JavaScriptの配列、オブジェクトをJSON文字列に変換するには、JSON.stringifyメソッドを利用する

Chapter4

・関数
与えられた入力に基づいて何らかの処理を行い、その結果を返す仕組み
デフォルトで提供されている関数もあるが、自分で関数を定義することもできる(ユーザー定義関数)

・関数を定義する方法

  • function命令で定義する
  • Functionコンストラクター経由で定義する(利用するメリットはない)
  • 関数リテラル表現で定義する
  • アロー関数で定義する

・関数名をつける際の注意点

  • 識別子の条件を満たす必要がある
  • どのような処理を担っているのか、がわかるような名前をつける
  • 「showMessage」のように「動詞+名詞」で命名するのが一般的
  • camelCase記法で表すのが基本

・引数
関数の挙動を決めるためのパラメーター

・戻り値(返り値)
関数が処理の結果、呼び出し元に返すための値
関数の末尾にreturn命令を記述して指定する

・JavaScriptでは、関数はデータ型の一種
「getTriangle」関数を定義するとは、「getTriangleという変数に関数型のリテラルを格納する」ことと同意

・function命令は静的な構造を宣言する
→function命令はコードをコンパイルするタイミングで、関数を登録しているため、コードのどこからでも呼び出すことができる

・関数リテラル、Functionコンストラクターは実行時に評価される
→function命令とは異なり、実行時(代入時)に評価されるため、呼び出し元より先に関数定義を記述する必要がある

・スコープ
変数がスクリプトの中のどの場所から参照できるか、を決める概念

  • グローバルスコープ→スクリプト全体から参照できる
  • ローカルスコープ→定義された関数の中でのみ参照できる

・関数から複数の値を返すことはできない
配列、オブジェクトとして値を1つにまとめて返す必要がある

・高階関数
関数を引数や戻り値として扱う関数
ArrayオブジェクトのforEach,map,filterメソッドなどは高階関数

・高階関数において、引数として与えられる関数は、その場限りでしか利用されないことが多い
→名前付き関数よりも、匿名関数として与えたほうがコードがシンプルになる

Chapter5

・コンストラクターとは「インスタンスを生成する際に、オブジェクトを初期化する処理を記述するための特殊なメソッド」

・同一のクラスを元に生成されたインスタンスであっても、それぞれが持つメンバーは同一とは限らない

・インスタンス共通のメソッドを定義するには、コンストラクターでメソッドを定義する必要がある

・prototypeプロパティ
prototypeプロパティに格納されたメンバーは、そのクラス(コンストラクター)を元に生成されたすべてのインスタンスから利用できる

・インスタンス側でのメンバーの追加や削除が、プロトタイプオブジェクトにまで影響を及ぼすことはない

・プロトタイプの定義はドット演算子とリテラル表現が使える
→可読性などからリテラル表現が良い

・継承
元になるオブジェクト(クラス)の機能を引き継いで、新たなクラスを定義する機能
継承元クラスは「スーパークラス」、継承によってできたクラスは「サブクラス」

・ES2015からclass命令が導入された

・class命令
クラスを定義できる

・オーバーライド
基底クラスで定義された機能を派生クラスで再定義すること

・イテレーター
オブジェクトの内容を列挙する仕組みを備えたオブジェクト

Chapter6

・クライアントサイドJavaScriptプログラミング
→「エンドユーザーや外部サービスから何らかの入力を受け取って、これを処理した結果をページに反映させる」

・DOM
マークアップ言語で書かれたドキュメントにアクセスするための仕組み

・DOMは、ドキュメントを文書ツリーとして扱う
文書を構成する要素や属性、テキストなどをノードと呼ぶ
DOMは、ノードを抽出/追加/置換/削除するための手段を提供するAPIである

・何をするにせよ、要素を取得することがコーディングに基点になる

・getElementByIdメソッド
指定したid値を持つ要素をElementオブジェクトとして返す

・getElementsByTagNameメソッド
タグ名をキーに要素を取得する
複数が合致する場合があるため、戻り値はHTMLCollectionオブジェクト(要素の集合)

・getElementsByNameメソッド
name属性をキーに要素群を取得する
一般的にはフォーム要素へのアクセスで利用する
戻り値はNodeListオブジェクト(ノードの集合)

・NodeListオブジェクト
ノードのリストを表すオブジェクト
HTMLCollectionオブジェクトとほぼ同じもの

・getElementsByClassNameメソッド
class属性をキーに要素群を取得する

・querySelector/querySelectorAllメソッド
セレクター式で文書を検索し、合致した要素を取得する

・セレクター式
スタイルを適用する対象を特定するための仕組み

・querySelectorAllメソッドの戻り値は、条件に合致した要素を全て含んだNodeListオブジェクト
querySelectorメソッドの戻り値はElementオブジェクト(単一の要素)
最初から取得すべき要素が1つとわかっている、もしくは、要素群の最初の1つだけを取り出したい場合は、querySelectorメソッドを使う

・ノードウォーキング
あるノードを基点として、相対的な位置関係からノードを取得すること

・getXxxx/queryXxxxメソッドで特定の要素を取得したあとに、近接するノードはノードウォーキングで取得するのが一般的

・イベントドリブンモデル
ページの中で発生した様々なイベントに応じて対応する処理を呼び出し、実行するモデル

・イベントに対応してその処理内容を定義するコードの塊(関数)のことをイベントハンドラー(またはイベントリスナー)という

・イベントドリブンモデルでは以下を定義する必要がある

  • どの要素で発生した
  • どのイベントを
  • どのイベントハンドラー(イベントリスナー)に関連付けるのか

・addEventListenerメソッド
イベントリスナーを設定する

・イベントリスナー
同一要素の同一イベントに対して、複数紐付けられるイベントハンドラー

・クロスサイトスクリプティングを防ぐ手段
ユーザーからの入力値など外部からの入力値を、innerHTMLプロパティで出力しないこと

Chapter7

・ブラウザーオブジェクト
ブラウザ操作のための機能を集めたオブジェクト群

・ストレージ
ブラウザ内蔵のデータストア
キーと値の組み合わせでデータを保管する
ローカルストレージとセッションストレージに分類される

・Ajax
JSを利用してサーバー側と非同期通信を行い、受け取った結果をDOM経由でページに反映する仕組み
従来型のwebアプリは同期通信だった

・Ajaxアプリを実装する手順(昨今ではライブラリを利用して実装するのが一般的)

  • XMLHttpRequestオブジェクトを生成
  • サーバー通信時の処理を定義
  • 非同期通信を開始

Chapter8

・単体テスト
関数、クラス(メソッド)単体の動作をチェック

・結合テスト
複数の関数、クラス(メソッド)を結合したときの動作をチェック

・システムテスト
アプリ全体の動作をチェック