Rのつく財団入り口

ITエンジニア関連の様々な話題を書いているはずのブログです。

【感想】『JavaScript Primer 迷わないための入門書』でモダンJS再入門 #jsprimer

JS完全に理解した……(し て ま せ ん)

 見出しはエンジニア界隈でお馴染みのダニング=クルーガー曲線のアレでございます。2020年6月に出たばかりの最新のJS本を読んだので書評です。
 570ページ余りの分厚さで電子版もあり。著者はECMAScriptの仕様にも関わっているazuさん、Angular日本ユーザー会代表のSuguru Inatomiさんと強力な布陣。ES2015(ES6)以降も進化を続けるJavaScriptについて、完全にES6をベースにしたモダンな入門書となっています。
 コンテンツはGitHubで管理されてオープンソースとして執筆され、様々な人がコントリビュートした結果が反映される面白い作り方になっています。Web版もすべて無料で参照できるのですが、こういう体系的な情報はまとまった本で学ぶことにしているので電子版で読みました。

 僕も2017-2018年ごろに掛けてJS&フロントエンド技術には再入門して、あれこれ本を読んだり3つの有力フレームワークを学んだり比較した結果を【JavaScript】3大フレームワーク Angular, React, Vue.jsを比べてみよう (2018年4月) - Rのつく財団入り口の記事にしたらなんか沢山アクセスがあったり、実案件でも実戦投入してきました。
規模の大きい開発にNode.jsビルドシステムを導入してリファクタしたり、用が足りると判断した案件では伝統のjQueryを使ったり、最近は見た目重視の案件にVue.jsを投入したりしています。社内の周囲ではJSもできるマンという感じになっています。
 では(本来の意味で)JSを完全に理解しているか……というとけっこう怪しくて、使ってない構文もあればまだまだ理解しきれていないところもあります。またエンプラ世界の辛みで2020年の今もIE11の亡霊がなかなか絶滅してくれず、泣く泣くIE11でも動く古い書き方で留めておいたりすることもあります。(まあBabelとかもありますが。)

 最近のフロントエンド人気にあやかってググっても大量に出てくるJavaScript情報でも、うっかり油断すると変数宣言が未だにvarだったり、古い情報や既に正しくなくなっている情報も出てきます。まとまった信頼できる情報を手元に置いておきたいなあとはよく思っていました。
 『改訂新版JavaScript本格入門』という良本があるのですが、物理本を会社に残したままテレワークに突入してしまったので、これを機に改めて読んでみることにしました。

第1部 基本文法

第1章 JavaScriptとは~ 第6章 演算子

constは再代入できないけどオブジェクトだと中のプロパティは変えられるので厳密には定数ではない、nullとundefined の比較……などやっぱり頭から抜けてた情報がありました。デバッグ方法やエラーの種類も書いてあるのがいいですね。

第7章 暗黙的な型変換

ここを読んでこれからは厳密等価演算子=== を常に使おうと固く決意して、今のプロジェクトのコードにも適用しました。(笑)
falsyになる6種類の分類も雰囲気でやってたので明示的な解説がありがたいです。

第8章 関数と宣言、第9章 文と式

8章はよく忘れがちなアロー関数の話、9章は文と式は別で文はセミコロン必要という話。
全体的に本書はコード例も簡潔で良いですね。そしてつくづくJavaScriptの初期仕様はバグを出しやすい曖昧さがあちこちにあったんだなあと思います。

第10章 条件分岐

If文の中に変数を書くとfalsyかどうかで判定する。ということは「文字列がundefinedでもnullでも空文字でもない」を判定する時は if (varName) {....}だけでいいのか...!

f:id:iwasiman:20200801111131p:plain
ネタ画像ですいません

第11章 ループと反復処理

配列の forEach, filter, someの後はコールバック関数であれば良いのだから、アロー関数にしなければもしやES2015以前のIE11用コードでも使えるのかな...? などなど、曖昧に使っていたところにけっこう知識の抜けがありそました。

第12章 オブジェクト

JSでよく出てくるオブジェクトのおさらい。厳密にはキーと値の組のことをまとめて「プロパティ」と呼ぶのは地味に知らなかった...!
キーの存在確認はundefinedとの比較より、in演算子hasOwnPropertyメソッドの方が安全なんですね。
Object.keys以外にもES2017で列挙メソッドが増えたり、進化が続いているなあという印象です。

第13章 プロトタイプオブジェクト

普段目にしないのでよく忘れる、Object.prototypeというプロパティにオブジェクトが入っており組み込みオブジェクトはみんなこれを継承しているから組み込み関数が使えるよという話。例が簡潔かつ豊富で判りやすいです。

第14章 配列

よく出てくる配列の話。配列もオブジェクトの一種だけどArray.isArrayは配列かどうかだけを判定してくれるんですねえ。
findIndex, find, includesなどES2015以降の便利メソッドも増えているので、意識して新しい方を使っていかなければと思いました。IE11さえ、IE11さえいなければ...(呪呪呪呪呪)
列挙されると分かる、filterやreduceなどコールバック関数が必要な高階関数群。Array-likeなオブジェクトもあったりしてややこしい。破壊的メソッドと非破壊適用メソッドも名前から区別できれば良いのですが、そうもいかないですね。

第15章 文字列

頻出の文字列操作のあたり。sliceメソッドとsubstringメソッドの挙動が微妙に違うなど、なんでこういう言語仕様にしたんだろうなあと思います。JSにはいままでString#startWithがなかったなど細かな発見もありました。
正規表現は普段はリテラルから、変数を使う場合はRegRxpクラスのコンストラクタから使うとGood。
match, exec, testと動作が少しづつ違う。コードの意図を判りやすくするにはStringクラスのメソッド群、柔軟な操作には正規表現を。
あまり使わないので曖昧になってた正規表現周りが整理できました。タグつきテンプレート関数は普段使わないのであまり理解できず……。

第16章 文字列とUnicode

文字列の内部処理。絵文字も入ってくると文字コードの世界は奥が深い...!

第17章 ラッパーオブジェクト

プリミティブ型の値にも裏で自動的に変換が掛かるので文字列からStringクラスのメソッドが呼べるんだよ、という話。JSでは常にリテラルを使うのがお作法。JSは「すべてがオブジェクトのように見える」言語だという話は納得です。

第18章 関数とスコープ

外側のスコープを順に見ていくのを「スコープチェーン」と呼ぶのは改めて知りました。
そしてJS特有の巻き上げの話。varによる変数宣言は宣言だけがより外側の関数かグローバルスコープに移動するので、この不思議な動きをするんですね。つくづくES2015までの世界のインターネッツのwebサイト群はよくこんな仕様の言語で壊れずに動いてたなと思います。
そして関数が状態をもったように振る舞ってくれるクロージャーの理解のカギは、JSの静的スコープとメモリ管理の仕組みである。この辺も難しいのですが、サンプルが明確なのでなるほど...!となります。

第19章 関数とthis

JSでよくハマるthisの挙動の話がしっかり解決してあります。
普通に関数宣言したらundefined 、オブジェクトの中のメソッドから呼ぶとベースオブジェクトになる。
実はcall, apply, bindという明示的にthisを指定できる関数があるのは完全に忘れていました。

そしてよく問題になる、コールバック関数の中でthisを使う話。対処法は組み込み関数に引数として渡せるなら渡す、一時変数へ代入しておくというのはよく実際の開発時もやりますね。

そしてES2015以降のオススメが出ましたアロー関数で、常に外側の関数のthis を指すから分かりやすい...というもの。例をもとに明確に書いていてありがたいです。ES2015の仕様を策定した偉い人も通常の関数ではthisを使うべきではないと述べているそうで、このへんJSは難儀な言語だなぁと改めて思います。

第20章 クラス

JSでも遂に書けるようになったクラス構文やsetter, getter。staticメソッドも書けるというはよく知りませんでした。 そしてclass 構文で書いたプロトタイプメソッドより、個々のインスタンスのコンストラクタに書いたインスタンスメソッドの方が優先されるというあたりもJS独特です。

そしてこれも独特なプロトタイプオブジェクトの話へ。インスタンスからクラスで定義したメソッドを呼べるのは、内部的にprototypeへの参照を持っているから。なるほどChromeの開発者ツールで見ると時々出てくる __proto__ はこの辺と関係しているんですね。

第21章 例外処理

Errorオブジェクトの種類などが明確に説明されています。

第22章 非同期処理: コールバック /Promise/Async Function

JSでは非同期処理は「並行処理」、メインスレッドの中で切り替えながら行われる。名前はよく聞くWeb Worker APIの完全な非同期処理は「並列処理」で両者は違うもの。このへん日本語が混乱しがちです。
非同期処理では例外をキャッチできないのは実は知りませんでした。
そして今までのJSでコールバック関数の第1,2引数に渡るものでエラーを判別していたものは「エラーファーストコールバックスタイル」とちゃんと名前がついていました。

そして非同期処理をより簡単に表現しよう...と導入されたPromiseの話。予め成功時、失敗時の動きを関数で定義して引数で渡して実行することができます。メソッドチェーンは本書ではPromiseチェーンと呼んで三重、四重の処理をしたり。
本書の例は全体的に分かりやすいのですが、構文に慣れていないせいかPromise周りは難しく感じました。
非同期処理すべてが終わったら先に行く Promise.all, 一番最初に終わった処理だけ採用のPromise.race, そしてES2017から使えるようになる、より簡潔に書けるようになる async function
難しいですがこのへんは極めると色々応用が効きそうです。Promiseについてだけ別の本をPDFで作ったそうですが、確かに奥がかなり深そうです。

第23章 Map/Set

JSにありそうで今までなかったMapとSet。オブジェクトを使う場合との比較など。使い方は他の言語とほぼ同じです。

第24章 JSON

JSON.stringifyに第2引数以降があるのはよく知りませんでした。

第25章 Date

言語仕様の分だけだと足りないところもあるDate周り。なるほど機能不足を補うために時々聞くライブラリのmoment.jsなどが出てくるのですね。

第26章 Math ~ 第27章 ECMAScriptモジュール ~ 第28章 ECMAScript

第1部の終わりにはモジュール機能の話、そしてJSの仕様が2015年以降毎年新しくなって進化している話が述べられています。
世の中の情報が膨大で間違っていることもあるので、適切な調べ方をもっておくことが大切...というのはなるほどなと思います。次の第2部は3つのユースケースを題材にした実際の開発での実践編です。

第2部 ユースケース

第29章 アプリケーション開発の準備〜第30章 ユースケース: Ajax通信

Node.jsを入れたりよくやる準備をしていざ開発へ。
最終的にはローカルで立てたサーバーで画面に入力したidを元に、GitHubAPIと通信してユーザー情報を取得して表示する画面を作っていきます。最初はサンプルコードがイベントの中に長い処理がすっぽり入ってかなり不格好ですが、どんどんリファクタリングされて分割され綺麗に整っていきます。

通信はES6以降のFetch APIを使っていて、ここもついjQueryのメソッドを使っちゃったりするので従来のやり方から切り替えないとなと思いました。
そしてPromiseを使って実装すると、前の処理の結果をラップして次の処理に渡していけるんですね。さらにasync functionを使って書くとサーバーサイドの言語の順次処理のように簡潔に書けます。同期処理と非同期処理が両方あっても連鎖できるのがポイントですね。このへん実際使って慣れていかないとなあと思いました。

第31章 ユースケース: Node.jsでCLIアプリケーション

拡張子.mdのファイルを読み込んでHTMLを出力するコンソールアプリケーションを作っていきます。追加するライブラリはcommander, markedなど。オプションをデフォルト設定して起動時の指定を有線する所などは他の言語と同じ感じ。この章の例は分かりやすいですね。
外部ファイルの読み込みはES moduleの標準でなくCommonJSモジュールを使っていて一般的にはどっちが多いのだろうと思いました。

第32章 ユースケース: Todoアプリケーション

JSの例でよく出てくるToDoアプリを開発します。最初は画面をそのまま実装し、DOM要素に直接値を持たせると限界があり、またどんどんイベントを登録していくと複雑になる一方である……と従来のやり方の問題点を提示します。
その後は状態やデータを別に持つModelクラスに分離するやり方を導入します。

さらにフロントエンドでよくあるObserverの考え方を導入、EventEmitterクラスを作ります。これも分かると何のことはなくてイベント名、コールバック関数の組で処理を貯めてSetに保持、外側からイベント発生時に emit されたら貯めてある中からコールバック関数を取り出して発動させるだけなんですね。これがModelクラスの親になるのが肝か。

最終的にはHTMLを描画する部分もViewクラスに切り出して、MVVMアーキテクチャ的なクラス構成になります。なんとなく思想的にはJSフレームワークのVue.jsに近い感じがしました。ViewクラスでDOM要素を描画しているところはReactっぽくもあります。メイン処理のAppクラスが役割的にはViewModelに近いような形でしょうか。
最終的にはリファクタリングして綺麗になるのですが、ピュアJSのみ(=いわゆるバニラJS)で書くと、それでもコード全体は結構な量になります。これをより短く書けるJSフレームワークやライブラリが生まれる訳だなあと思いました。

まとめ:JS完全に理解した……の先へ行ける、モダンJSのまとまった最新情報が得られる本!

 と読書メモを並べてみましたが、自分的には案の定というべきか、忘れているところ、理解があやふやなところがあちこちにありました(汗)。よい補完になりました。特に難しいと思ったのはやはりPromise周りでした。改めて理解を深めないと……。
 複数の方が関わってコントリビュートしていることもあり、日本語の文章は読みやすいです。このへんは翻訳本に比べると強みですね。また全体的にコード例が豊富かつ簡潔で、(難しいところは難しいのですが)理解しやすいと思います。他の難しそうな本で挫折したという方も本書ならリベンジできるのではと思います。

 本書のTwitterハッシュタグ #jsprimer を概観していると多くの人が呟いているのが、「今まで雰囲気でやっていた/理解していたところがよく分かった」というもの。僕も同じような感想を持ちました。変化を続けるJavaScriptについてまとまった、かつ今後もアップデートが期待できる情報源として、学習の傍らや実際の開発の傍らで大いに役立つことでしょう。

f:id:iwasiman:20200801111131p:plain
JS完全に理解した……の先へ!

JS完全に理解した……の先へ行けるリンク集

本と同じ内容のWeb版。最後の『付録:JavaScriptチートシート』が解説ページそれぞれに飛べてとても便利です。

jsprimer.net

本書の続編の位置付けに『JavaScript Promiseの本』も無料公開されています。Promiseだけで一冊本ができるのが凄い……! それぐらいPrromise周りは難しく奥が深いということですね。

azu.github.io

コンテンツ自体がオープンソースとして管理された本書のGitHubリポジトリ

github.com

達人出版会からも出版されています。

tatsu-zine.com

はてブ300の大注目を浴びた、なぜ書かれたかの記事。

efcl.info

Web版を読んでJSに再入門した方の記事。

pagain.hatenablog.com

Web版を読んだQiitaの感想記事。

qiita.com

本書でArrow Functionが分かった方の記事。

https://www.ry0takahash1.com/archives/20200728.htmlwww.ry0takahash1.com

本書で学習を始めた方の記事。

自分用メモ JavaScriptの勉強を始めた #jsprimer - Mitsuyuki.Shiiba

500はてブと注目された、Ruby界隈やQiitaでお馴染みの伊藤淳一さんの感想記事。タイトルに埋め込まれたギャグにもっとツッコミを入れて欲しかったそうであります。
『「すでに他の言語のプログラミング経験はあるし、JSもある程度触れるが、ES2015以降の機能は雰囲気でしか理解していない」という人間にはピッタリの一冊でした』という感想に納得です。

blog.jnito.com

JS完全に理解した……の先に行ける、モダンなJSが学べる最近の本

本書の作者さんによる、レベル別のJS本のおすすめリスト。JS本も列挙すると色々あるのですが、2010年代後半~の新しい本があまりないんですよね。

JavaScriptのレベル別書籍のまとめ · GitHub

『改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで』が初版2016年。2019年10月に6版でES2015の情報も強化され、電子版にも更新が入っています。
技術書では安心の山田 祥寛さんの本。評判も良く、言語経験があってJS再入門したい方には今もお勧めです。僕がJS再入門したのもこの本です。リファレンス用に会社の机に1冊置いてあるのですが、今ごろ埃をかぶってるだろうか……

Amazonでベストセラーになっている『確かな力が身につくJavaScript「超」入門』は2019年9月の最新。前述の本よりややランクを落とし、より初心者向け。開発経験のない方、浅い方はまずはここからしっかりやるのも良いと思います。

山田祥寛さんの速習シリーズは『速習ECMAScript 2020』 が2020年刊行。『速習ECMAScript 6』『速習ECMAScript 2019』を改定した最新になっています。こういう薄い本はバージョンアップに対応しやすくてよいですね。

 約束のオライリー本ですと、電子版がないですが『初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発』のが2017年1月刊行でぎりぎり最近といえるでしょうか。450ページあります。前述のレベル別リストだとこれも初心者向けの分類となっています。
 「サイ本」として有名な『JavaScript 第6版』はさらに鈍器力の高い800ページ越え、こちらは2012年刊行で古めです。この2冊は表紙デザインがやや似ているので注意です。(「初めての~」の表紙はカバさん?)

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

  • 作者:Ethan Brown
  • 発売日: 2017/01/20
  • メディア: 単行本(ソフトカバー)

JavaScript 第6版

JavaScript 第6版

コードサンプルが大量に載ったスタイルの本ですと、JavaScript コードレシピ集』が2019年1月、JavaScript逆引きレシピ 第2版』が2018年10月。

JavaScript コードレシピ集

JavaScript コードレシピ集

JavaScript逆引きレシピ 第2版

JavaScript逆引きレシピ 第2版