サイ本こと『JavaScript 第6版』全800ページを読破し、1万行のesaにまとめてわかった5つのこと
しがないラジオのgamiです。
JavaScript界隈では有名な、オライリーのサイ本こと『JavaScript 第6版』という鈍器、もとい書籍を読みました。

- 作者: David Flanagan,村上列
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/08/10
- メディア: 大型本
- 購入: 12人 クリック: 252回
- この商品を含むブログ (18件) を見る
2012年に発行された、約800ページもある、かなり内容の多い本です。 僕は本を読むときにesaに要約しながら読み進めるのですが、サイ本のまとめesaは全体で「約1万行」という修行みたいな分量になっていました。
サイ本、3年越しくらいでやっと読み終わったあああああ!!!esaにまとめながら読んでたけど、コードも含めて約23万字、1万行の分量になっててesaが悲鳴あげてたw今度感想ブログ書く。多くの人には読む必要の無い本だけど、Web周りのJavaScriptの世界を概観するにはよかった。https://t.co/Ym3D5VRIgW
— gami@しがないラジオ (@jumpei_ikegami) 2018年6月24日
サイ本を要約しながらじっくりJavaScriptを学んだ人はこの世界にあまりいないと思うので、わかったことをまとめます。
読み始めたきっかけ
僕は約2年前に、富士通から、今働いているプレイドという会社に転職しました。 富士通ではCOBOL(!)とJavaしか書いていなかったので、Node.js+Vue.jsの会社に転職するための準備として、『JavaScript 第6版』を買った記憶があります。
今思えば、もっと軽い入門書もあったと思います。中二病だったのでしょう。
『JavaScript 第6版』を読んでわかった5つのこと
サイ本を読んで、JavaScriptのプログラミング言語としての立ち位置や面白さがわかりました。
「JavaScriptを学ぶ」ことの多くは、「ブラウザの仕様を学ぶ」こと
サイ本は、大きく「コアJavaScript」と「クライアントサイドJavaScript」の2部に分かれています。「コアJavaScript」では、主にJavaScriptの文法について説明しています。型、演算子、文、関数、正規表現など、他のプログラミング言語の入門書でも必ず説明されるような内容です。
特徴的なのは、「コアJavaScript」よりも「クライアントサイドJavaScript」の方により多くの紙幅を割いている点です。他のプログラミング言語の入門書であれば、簡単にライブラリを紹介する章はあっても、言語自体の文法に関する説明よりも短く掲載される場合がほとんどでしょう。JavaScriptの場合は、「Webブラウザ」という切っても切り離せない巨大アプリケーション群があり、ほとんどの場合はその実行環境を前提として記述されます。そのため、「JavaScriptを学ぶ」ということの多くは、「ブラウザの仕様」や「DOMを含むWeb API群の標準仕様」を学ぶということなのだなあ、ということをサイ本を読んで実感しました。
JSのクライアントサイドAPIをちゃんと学ぶと、ドキュメントのレンダリングとかフォーム部品とかiframeとかイベントハンドリングとかCookieとかHTTPとか、Webフロント周りの知識が一通り身につくので、すごくいいと思った. サイ本を読めとは口が裂けても言えないが、JSを通じてWebを学ぶのはおすすめ.
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月22日
例えば、ただJavaScriptで計算をしたいだけなら、別にWebページのHTMLをどのように操作できるかなど知らなくても何も困りません。ただし、JavaScriptを書きたい、学びたい、というモチベーションの多くは、Webのクライアントサイドに関わる以下のようなことです。
- 動的にHTMLやCSSを変化させたい(DOMやCSSOMの制御)
- ユーザーの操作に応じて処理を変えたい(イベント処理)
- 外部サーバーと非同期で通信したい(Ajax)
- ブラウザ側にデータを保持して、IDやセッションを管理したい(Cookie、localStorage)
サイ本の13.3.4『クライアントサイドJavaScriptのタイムライン』がめっちゃいい. WebページのJS実行順が詳細に書いてある. document.write()、async属性、defer属性が全て考慮され、document.readyStateとwindowのloadイベントのタイミングが書いてある. 当たり前の情報だけど、ありがたい.
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月13日
逆にクライアントサイドJavaScriptは、それを学ぶ過程で、HTMLやCSSの仕様に依存したAPIを学ぶことになります。なので、Webのクライアントサイドの技術について深く学びたい場合は、JavaScriptの学習をすることで、HTMLやCSSも含めたブラウザの仕様について深く理解できるようになると思います。
ちなみに、2007年に発行された一つ前の版である『JavaScript 第5版』の目次を『JavaScript 第6版』のものと比べると、ブラウザの機能の変遷がわかって非常に面白いです。
2007年の第5版では「Javaアプレット」、「Flash」、「XML」などの章がありますが、2012年の第6版ではそれらがすべて削除され、代わりに後述する「jQuery」や「HTML5 API」の章が追加されています。
クライアントサイドJavaScriptの爆発的変化
『JavaScript 第6版』が出版されたのは、2012年の8月です。今が2018年の7月なので、たった6年前になります。ただし、この本に書かれている内容ですら、すでに一部の仕様が廃止されていました。
例えば、windowオブジェクトのメソッドとして本書で紹介されているshowModalDialog()
は、MDNで調べると「この機能は削除されました。ウェブサイトやアプリケーションを修正してください。」と書かれています。
サイ本に書いてあるwindow.showModalDialog()がChromeやFirefoxでは廃止されているというこの世界の希望. 要らない仕様はブラウザベンダーが結託して消していって欲しい. 強気MDN萌え:「この機能は削除されました。ウェブサイトやアプリケーションを修正してください。」https://t.co/jMpefmNge9
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月15日
「ブラウザは後方互換性を大事にするので機能を削除できない」とよく耳にしますが、仕様の議論が不十分なままブラウザに実装された過去の機能については、廃止されているものもあるようです。
サイ本に「keypressイベントを代替する次世代のテキストイベントや!(意訳)」とドヤ顔で書いてある"textinput"イベントさん、MDN検索しても全く出てこないので、消滅したという認識でよろしいか?
— gami@しがないラジオ (@jumpei_ikegami) 2018年4月13日
サイ本を読むとき、あまり聞いたことのない機能については、実際にブラウザのコンソールで本当に使えるのか試したり、MDNに記載があるかを調べたりしていました。少し古めのJavaScript本を読むときは、機能が廃止されている可能性を考慮しながら読んだ方が良さそうです。
なお、JavaScriptはES2015で以下のような新しいシンタックスがかなり追加されましたが、サイ本にはそれに関する以下のような記載はありません。
let
、const
による変数宣言- アロー関数
class
構文- 分割代入
- importとexport
さらに、現代のクライアントサイドJavaScriptとは切っても切り離せない以下のような技術スタックには特に触れられていません。
- webpackなどのモジュールバンドラ
- Vue.jsなどのJavaScriptフレームワーク
- TypeScriptなどのAltJS
フロントエンドの開発に求められるものの多様化とWeb技術の変化の速さを揶揄して「フロントエンド地獄」と呼ばれますが、サイ本もまた(少なくとも第6版の時点では)その地獄に囚われ古臭い本になりつつありました。
そのためサイ本は、「最新のJavaScript」ではなく、「時代を経ても変わらないJavaScriptのエッセンスや、すでに安定したWeb API」について学ぶための本として読んだ方がよいです。
「最新のJavaScript」については、出版されるかわからない『JavaScript 第7版』に期待しましょう。
ブラウザ間の差異から来る闇
JavaScriptという言語の特殊性として、その実装はブラウザベンダーに委ねられており、独自の方言が認められている点があります。もちろん、Webページを実装する開発者としては、1つのJavaScriptファイルが複数のブラウザで意図通りに動作することを期待します。ただし、歴史的経緯から来るブラウザ間の仕様の差異によって、その期待はしばしば裏切られてきたことが、サイ本を読むとわかります。
特に、Web標準の策定プロセスが今ほど洗練されていなかった時代に実装された機能については、多くの闇を生み出しているようです。例えば、window.onerror
というエラー時に呼び出される関数内では、エラー処理完了時に通常はfalse
を返します。ただし、歴史的経緯から、Firefoxだけはtrue
を返さなければいけないそうです。
サイ本. window.onerror内でエラー処理が完了したら通常falseを返すべきだけど、Firefoxだけはtrueを返さないといけないらしい. 『残念ながら、歴史的な理由により、Firefoxのエラーハンドラでは、ハンドラがエラーを処理したことを示すためには、trueを返さなければなりません』. 歴史的な理由とは?
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月15日
このような問題に対処するには、本来の処理に加えて、どのブラウザで実行されているのかをチェックする「ブラウザテスト」を実施しなければいけません。
(なお現在では、window.onerror
はtry-catch
によって代替され、ほとんど使われていません。)
特にブラウザ互換性についての話題で言及されやすいInternet Explorer(IE)については、本書でも「非互換性の多くは、IEに関連したものです」と、名指しで批判されています。
サイ本13.4.6「実際のところ、クライアントサイドJavaScriptでの非互換性の多くは、IEに関連したものです。」くそわろたwww
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月13日
古いIEでは、Web標準として勧告されたメソッドを実装せず、同様の機能を持った別名のメソッドを使っていたりします。
例えば、IE8以前ではイベントハンドラを登録するaddEventListener()
が実装されていなかったため、代わりにattatchEvent()
というメソッドを使う必要があったそうです。
if (window.addEventListener) window.addEventListener("load", f, false); else if (window.attachEvent) // IE8以前 window.attachEvent("onload", f);
IEが天下を取っていた時代は、大半のWebページはIEで動けば問題なかったのでしょう。そんなIEに対抗するブラウザが登場し、健全な競争や議論の中でWebの標準化が進んだことは、非常に喜ばしいことだと思います。
サイ本. かつてはIEでしか動かないこんなページが存在したのか...闇...
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月10日
<script type="text/vbscript">
' VBScriptコードを記述
</script>
また、Web標準の策定プロセスが整備されたことに加えて、Microsoft Edgeの登場、ブラウザ間の差異を埋めるPolyfillなどのライブラリの存在によって、ブラウザ間の差異を前ほど意識せずにJavaScriptを書くことができる環境になりつつあります。
かつてのjQueryがもたらした価値
サイ本では、第19章の約70ページ全てを、丸々jQueryの紹介に割いています。JavaScriptの1ライブラリとしては、破格の待遇です。
2012年当時、jQueryがJavaScriptライブラリとしてデファクトスタンダードであったことがわかります。
今でこそ目の敵にされているjQueryですが、当時これほど流行った理由がサイ本を読んでいてわかりました。
前述のように、当時のフロントエンドの開発者はブラウザ間の差異から来る闇に苦しんでいました。生のJavaScriptではなくjQueryを使うことで、ブラウザ間の差異を吸収してくれ、どのブラウザでも同じように動作するJavaScriptを生成することができました。
サイ本にjQueryの章が約70ページもあるところを見ると、ブラウザ間で実装がバラバラだったJavaScriptを使う上で、jQueryがいかに重要な役割を担っていたかがわかる!
— gami@しがないラジオ (@jumpei_ikegami) 2018年5月3日
また、JavaScriptやブラウザ自体の機能がまだ脆弱だった頃、jQueryは強力なAPIをどんどん追加していき、JavaScriptができることを広げていったようです。
サイ本のjQuery章読み終わったけど、改めてjQueryは高機能かつAPIが強力すぎてすごいな。animationのqueue機構とか、ajax周りとか、強すぎる。逆にjQueryに頼りすぎてカオスになるという意味で、危険さを実感した。
— gami@しがないラジオ (@jumpei_ikegami) 2018年5月5日
jQueryのAPIを覚えるだけで、ブラウザ互換性に配慮した動的なWebページを開発することができるとなれば、これほど使われるようになるのも必然でしょう。
ただし、現在では前述のようにブラウザ間の差異を前ほど意識せずにフロントエンド開発ができる環境が訪れつつあり、jQueryが果たした本質的な役割の意義が薄れつつあります。
また、jQueryのようなDOMへの要素挿入を中心としたアプローチではなく、宣言的なViewの管理によって要件を実現するVue.jsなどのJavaScriptフレームワークが、保守性などの観点から流行しています。一般にVue.jsなどが管理しているDOMを後からjQueryで書き換えるとアプリケーションがぶっ壊れるので、脱jQueryを進めるWebページやWebアプリケーションが増えている印象です。
サイ本. 13.4「互換性と相互運用性」で当時のIEとMicrosoftがディスられている. JavaScriptの方言が強すぎた時代の通訳として、jQueryの価値が高かったのだろう. ESの標準化と実装差異の縮小とBabelの利用が進んだ現代においては、jQueryの通訳としての価値は無くなった.
— gami@しがないラジオ (@jumpei_ikegami) 2018年3月13日
もしも『JavaScript 第7版』が出版されたら、きっと『第19章 jQueryライブラリ』は無くなっているでしょう。
ブラウザにはワクワクする機能がたくさん追加されている!
サイ本の最終章である『22章 HTML5 API』では、以下のように当時では比較的新しかったAPIの仕様に関して言及されています。
- 履歴管理
- クロスオリジンメッセージング
- Web Workers
- Geolocation
- IndexedDB
この本では「未来のAPI」のように語られているこれらのAPIですが、例えば「履歴管理」はSPAで戻るボタンを押せば当たり前のように機能しますし、Web Workersの1つであるService WorkersもついにiOS Safariで対応され、主要ブラウザ全てでPWAのキャッシュやプッシュ通知に使われ始めています。
ブラウザの仕様が目まぐるしく変わることで、そのキャッチアップが大変であったり、多くの負債が生まれたことは、前述の通りです。しかし、逆に新しい仕様が次々と登場することで、ブラウザで実現可能な範囲は毎年広がっています。例えば、「ブラウザ経由で位置情報を特定してその場所に応じたコンテンツを出す」みたいなことも、ブラウザの標準機能で実現できるようになっています。
navigator.geolocation.getCurrentPosition(function(pos) {...});をMac版Chromeのコンソールで実行したら、かなり詳細に緯度経度特定されてびびった。サイ本を信じるならGPSが無くてもIPアドレスや検出可能な無線LANから特定するらしいけど、PCでもここまで特定できるのすごいな!
— gami@しがないラジオ (@jumpei_ikegami) 2018年6月24日
また、この本に書かれた後に登場してきた新しい仕様によって、以下のような世界が当たり前になっていくかもしれません。
- WebAssemblyで、C言語で書かれた世界中の資産がブラウザ上から使える
- Payment Request APIで、ブラウザに登録しておいた支払方法や配送先を選ぶだけでブラウザ経由で決済できる
- Web Publicationsで、HTMLで書かれた文書をそのまま電子書籍として閲覧、出版できる
JavaScriptを取り巻くエコシステムについて学び続けていると、そんなワクワクする話題がたくさん登場して、とても楽しい毎日を送れます。
この本について
ここまでサイ本を比較的ボジティブに解説してきましたが、正直に言って、JavaScriptを勉強したい多くの人には、この本はあまりおすすめではありません。『JavaScript 第6版』自体がかなり古くなっていて、最新のJavaScript事情を反映できてないからです。また、リファレンス的に利用するならまだしも、全章を読破するには、JavaScriptを記述する上では不要な内容が多い印象があります。
僕もJavaScriptを学び始めた当初は、サイ本より先に、『開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質』という本を読みました。

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
- 作者: Cody Lindley,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/06/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
こちらの本の方が、JavaScriptのハマりポイントである以下のような点について、たくさんの例を交えて簡潔に記述されています。
- プリミティブ型とオブジェクト
- this
- スコープとクロージャ
- プロトタイプ継承
JavaScript初心者が中級者に上がるための本としては、こちらの『開眼! JavaScript』の方をおすすめします。
また、リファレンス的に利用するにしても、MDN Web DocsにJavaScriptの最新仕様やブラウザ互換性についてよくまとまっているので、そちらの方が使い勝手としては良いでしょう。
「サイ本がこれだけ分厚いなら、JavaScriptのより低レイヤな領域についても記載があるだろう」と思う人もいるかもしれないですが、特にメモリ管理の話とかも出てこないです。
なので、仮に『JavaScript 第6版』を勧めるとしたら、「ある時点でのJavaScriptの仕様を、その歴史も交えて体系的に知りたい」人に対してのみになるかと思います。もしそのような奇特な人がいたら、ぜひ挑戦してみてください。
最後に、改めてサイ本こと『JavaScript 第6版』の目次を掲載します。
- 訳者まえがき
はじめに
1章 JavaScriptの概要
- 1.1 コアJavaScript言語
- 1.2 クライアントサイドJavaScript
第I部 コアJavaScript
2章 字句構造
3章 型、値、変数
- 3.1 数値
- 3.2 テキスト
- 3.3 論理値
- 3.4 nullとundefined
- 3.5 グローバルオブジェクト
- 3.6 ラッパーオブジェクト
- 3.7 不変な基本型値と可変なオブジェクト参照
- 3.8 型の変換
- 3.9 変数の宣言
- 3.10 変数のスコープ
4章 式と演算子
5章 文
- 5.1 式文
- 5.2 複合文と空文
- 5.3 宣言文
- 5.4 条件文
- 5.5 ループ文
- 5.6 ジャンプ文
- 5.7 そのほかの文
- 5.8 JavaScript文のまとめ
6章 オブジェクト
- 6.1 オブジェクトの生成
- 6.2 プロパティの読み出しと書き込み
- 6.3 プロパティの削除
- 6.4 プロパティのテスト
- 6.5 オブジェクトプロパティの調査
- 6.6 プロパティのゲッターメソッドとセッターメソッド
- 6.7 プロパティ属性
- 6.8 オブジェクト属性
- 6.9 オブジェクトのシリアライズ
- 6.10 オブジェクトのメソッド
7章 配列
- 7.1 配列の生成
- 7.2 配列の要素の読み書き
- 7.3 疎な配列
- 7.4 配列の長さ
- 7.5 配列の要素の追加と削除
- 7.6 配列の要素の巡回
- 7.7 多次元配列
- 7.8 配列のメソッド
- 7.9 ECMAScript 5の配列メソッド
- 7.10 配列の種類
- 7.11 配列のようなオブジェクト
- 7.12 配列としての文字列
8章 関数
- 8.1 関数の定義
- 8.2 関数の呼び出し
- 8.3 関数の引数と仮引数
- 8.4 値としての関数
- 8.5 名前空間としての関数
- 8.6 クロージャ
- 8.7 関数のプロパティとメソッドとコンストラクタ
- 8.8 関数型プログラミング
9章 クラスとモジュール
- 9.1 クラスとプロトタイプ
- 9.2 クラスとコンストラクタ
- 9.3 JavaScriptでのJavaスタイルのクラス
- 9.4 クラスの拡張
- 9.5 クラスと型
- 9.6 JavaScriptでのオブジェクト指向的な技術
- 9.7 サブクラス
- 9.8 ECMAScript 5のクラス
- 9.9 モジュール
10章 正規表現パターンマッチング
11章 JavaScriptのサブセットと拡張
- 11.1 JavaScriptのサブセット
- 11.2 定数とスコープ付きの変数
- 11.3 分割代入
- 11.4 反復機構
- 11.5 簡易表記関数
- 11.6 複数のcatch節
- 11.7 E4X:ECMAScript for XML
12章 サーバサイドJavaScript
第II部 クライアントサイドJavaScript
13章 Webブラウザに組み込まれたJavaScript
- 13.1 クライアントサイドJavaScript
- 13.2 HTMLドキュメントへのJavaScriptコードの埋め込み
- 13.3 JavaScriptプログラムの実行方法
- 13.4 互換性と相互運用性
- 13.5 アクセサビリティ
- 13.6 セキュリティ
- 13.7 クライアントサイドフレームワーク
14章 Windowオブジェクト
- 14.1 タイマー
- 14.2 ブラウザのLocationオブジェクトと移動
- 14.3 閲覧の履歴
- 14.4 ブラウザと画面情報
- 14.5 ダイアログボックス
- 14.6 エラー処理
- 14.7 Windowプロパティとしてのドキュメント要素
- 14.8 複数のウィンドウとフレーム
15章 ドキュメントの制御
- 15.1 DOMの概要
- 15.2 ドキュメント要素の選択
- 15.3 ドキュメント構造と探索
- 15.4 属性
- 15.5 要素のコンテンツ
- 15.6 ノードの作成、挿入、削除
- 15.7 例:目次の作成
- 15.8 ドキュメントと要素位置とスクロール
- 15.9 HTMLフォーム
- 15.10 ドキュメントのそのほかの機能
16章 CSSの制御
17章 イベント処理
18章 HTTPの制御
- 18.1 XMLHttpRequestの利用方法
- 18.2
<script>
によるHTTP制御:JSONP- 18.3 Server-Sent Eventsを使ったComet
19章 jQueryライブラリ
20章 クライアントサイドストレージ
- 20.1 localStorageとsessionStorage
- 20.2 クッキー
- 20.3 IEのuserData永続化機構
- 20.4 アプリケーションストレージとオフラインWebアプリケーション
21章 メディアとグラフィックの制御
- 22.1 Geolocation
- 22.2 履歴管理
- 22.3 クロスオリジンメッセージング
- 22.4 Web Workers
- 22.5 型付き配列とArrayBuffer
- 22.6 Blob
- 22.7 Filesystem API
- 22.8 クライアントサイドデータベース
- 22.9 WebSocket
索引