Secrets of the JavaScript Ninja 2nd 読書メモ 第2章 実行時にページを組み立てる

Secrets of the Javascript Ninja

クライアントサイドWebアプリケーションのライフサイクル

  1. ユーザがブラウザのアドレスバーにURLを打ち込む
  2. ブラウザがリクエストを生成してサーバに送信する
  3. サーバがクライアントにレスポンスを返す
  4. ブラウザがHTML/CSS/JavaScriptを処理して最終的なページを組み立てる
  5. ブラウザがイベントキューを監視してイベントに応答できるようにする
  6. ユーザがページの要素を操作する
  7. ユーザがWebアプリケーションを閉じる

ページの組み立てのフェーズ

  1. HTMLを構文解析して、DOMを組み立てる
  2. JavaScriptコードを実行する

※JavaScriptエンジンは、script要素を見つけると、そこでDOMの組み立てを一時停止してJavaScriptを実行する。そのため、script要素がHTMLの途中にあり、読み込みや実行に時間がかかると、ブラウザの描画が停止してパフォーマンスが悪化して感じられる。script要素はbody要素の末尾に置くべきである。

イベントの取り扱い

クライアントサイドのWebアプリケーションはGUIアプリケーションなので、ユーザーの様々な操作(イベント)に反応する必要がある。

イベントハンドリングの概要

ブラウザの実行環境はシングルスレッドの実行モデルである。イベントは単一のキューに入れられ、上から順に1つずつ処理される。

イベントハンドラを登録する

イベントハンドラの登録には以下のいずれかの方法が使用できる。

// 特殊なプロパティに関数を代入する
window.onload = function(){};

// addEventListener メソッドの使用
document.body.onclick = function(){};

プロパティへの代入は、一度に一つのイベントハンドラしか登録できない。複数登録したい場合はaddEventListenerを使う必要がある。

Secrets of the JavaScript Ninja 2nd 読書メモ 第1章 JavaScriptはどこにでも

Secrets of the Javascript Ninja

JavaScript言語を理解する

JavaScriptは以下のような点で他の言語と異なる。

  • 関数がファーストクラスオブジェクトである
  • クロージャ
  • スコープ(ES2015より前には、JavaScriptにブロックスコープはなかった)
  • プロトタイプベースのオブジェクト指向

オブジェクトとプロトタイプ、関数とクロージャーの関係を理解することで、JavaScriptのプログラミングスキルが向上する。

加えて、以下のような機能を理解することで、美しく効率の良いコードを書くことができる。

  • ジェネレーター
  • Promiseによる非同期処理
  • Proxyによるオブジェクトへのアクセス制御
  • Arrayのメソッド群
  • Mapによる辞書型コレクション、Setによる一意なコレクション
  • 正規表現
  • モジュール

ブラウザを理解する

JavaScript実行環境としてもっとも重要なのはブラウザである。ここでは以下のトピックに集中する。

  • DOM(Document Object Model)
  • イベント
  • ブラウザのAPI

ベストプラクティスに従う

JavaScriptの習熟に加えて、以下のようなスキルを身につけていることが重要である。

  • デバッグ
  • テスト
  • パフォーマンス分析

スキルを持ち運びやすくする

JavaScriptのコアとなる部分について深い理解があれば、様々な種類のアプリケーション開発にスキルを活用できる。

  • デスクトップアプリ(Electron)
  • モバイルアプリ(Cordova, React Native)
  • サーバーサイドアプリ(Node.js)

Secrets of the JavaScript Ninja 2nd 読書メモ 0 はじめに

Secrets of the Javascript Ninja

『Effective C#』第3版のおかげで、洋書をちまちま読む習慣が身につきました。良い流れを切らさないよう、新しい本に手を付けてみます。次に読む本は『Secrets of the JavaScript Ninja』の第2版。jQueryの作者であるJohn Resig氏の著書で、第1版は「JavaScript Ninjaの極意」というタイトルで邦訳されています。本書は、2016年10月に発売された第2版で、ES6(ES2015)の文法も踏まえた最新版です。

今回は「はじめに(Author’s Introduction)」の部分からメモ。


JavaScriptを取り巻く環境は、著者が本書の初版を書き始めた2008年頃と比べると、様々な点で異なる。

  • JavaScriptはクロスプラットフォームで動作する言語として最大の人気を得ている
  • (JavaScript実行環境の)プラットフォーム間の差異は縮小傾向にある
  • 開発環境の進歩も著しい

JavaScriptの書き方は以前とは様変わりしている。本書には、新しい時代のJavaScriptを、上手に書くための知見がまとめられている。

Effective C# 3rd 読書メモ 50 例外フィルタの副作用を利用する

常にfalseを返す例外フィルタを定義することは奇妙に思えるかもしれないが、そうすべき理由がある。例外フィルタはスタックの一部として実行されるので、スタックが破棄される前に実行されるのだ。

これを利用すると、以下のように、例外の詳細な情報をログに書き込むことができる。

public static void Main()
{
    var failures = 0;
    var data = default(string);

    while (data == null)
    {
        try
        {
            data = MakeWebRequest();
        }
        catch (Exception e) when (ConsoleLogException(e))
        {
        }
        catch (TimeoutException e) when (failures++ < 10)
        {
            WriteLine("Time out error: trying again");
        }
    }
}

public static bool ConsoleLogException(Exception e)
{
    var oldColor = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Red;
    WriteLine($"Error {e}");
    Console.ForegroundColor = oldColor;
    return false;
}

private static string MakeWebRequest()
{
    throw new TimeoutException();
}

以上で、『Effective C#』の第3版、読了です。C#は仕様の大きな言語で、それなりの歴史もあるので、同じことをするにも複数の書き方ができます。典型的な例はローカル変数の定義で、型を明示的に指定することもできれば、型推論に任せることもできます。初心者のうちは、どちらの書き方を使えばいいのかわかりませんでした。

本書には、そういったC#を書く上での迷いどころや落とし穴の回避方法がまとめられています。『やさしいC#』等の入門書を読んだ後、2冊目ないし3冊目あたりで読むと良いと思いました。

ちなみに、『Effective C#』の類書として『実戦で役立つ C#プログラミングのイディオム/定石&パターン』があります。こちらは入門書の次に読んでも大丈夫なくらいの内容で、C#で何かをしたいときに役立つ書き方が「イディオム」としてまとめられています。

Effective C# 3rd 読書メモ 49 例外フィルタを使う

通常のcatch節では、例外の型に基いて捕捉を行う。例外をキャッチしたらリトライするような実装では、最終的に、例外を再度throwすることになる。このやり方では、その後の分析が難しくなる。このような場合には、例外フィルタを使うべきである。

例外フィルタは、catch節にwhenキーワードを重ねて使用する。

public static void Main()
{
    var retryCount = 0;
    var data = default(string);

    while (data == null)
    {
        try
        {
            data = MakeWebRequest();
        }
        catch (TimeoutException e) when (retryCount++ < 3)
        {
            WriteLine("Operation timed out. Trying again");
            Task.Delay(1000 * retryCount);
        }
    }
}

private static string MakeWebRequest()
{
    throw new TimeoutException();
}

例外フィルタを使用すると、例外をキャッチした際にもコールスタックは破棄されないので、例外の発生した状況をあとで追いやすい。また、例外フィルタを使用したほうがパフォーマンスも良くなる。