JavaScriptの基礎を学ぶためにjsprimerという無料の教材を読んで写経しました。
感想
内容は2部構成になっていて、1部でJavaScriptの基礎文法を学び、2部でサンプルのアプリを作成します。
無料ですが文法をしっかり学んだ上でアプリを作ることもできるので、Progateなどをやった後やReact、Vueなどのフレームワークをやる前のJavaScriptの言語仕様を学ぶに最適だと思います。
1部はRubyを学んでいたので、共通するような文法は流し読みでいけたのですが、クロージャーやthis
、非同期処理などの理解が特に難しかったです。
いろんな関数が出てくるので、関数の理解が特に重要だなと感じました。
2部では非同期処理を使ってGithubのAPIからユーザー情報を取得できるアプリ、Node.jsを使ってMarkdownをHTMLに変換するCLIアプリ、Todoアプリを作りました。
それぞれのコードの説明もされていて、動くコードを書いてからリファクタリングしていくやり方なので基本的にはわかりやすかったのですが、それでもTodoアプリのクラスや関数のつながりや処理の流れを追うのは大変でした。
静的解析ツール、テストなどの周辺のツールについての解説はないので、そこらへんは自分で調べる必要があります。
さっさとJavaScriptの基礎は理解して、Reactの勉強に入ろうと思います。
新しく学んだこと
新しく学んだ重要そうな部分をまとめておきます。
第一部
JavaScriptとは
- ブラウザだけでなくNode.jsというサーバー側のアプリを作る仕組みでも利用される
- JavaScriptはECMAScriptというどの実行環境でも共通で動作する仕様と、実行環境によって異なる固有の機能で成り立つ
- JavaScriptは大部分がオブジェクト
- 開発者が安全にコードを書けるように、
strict mode
という古く安全でない構文や機能の一部が禁止される実行モードが存在する - デフォルトの実行コンテキストである
Script
と、ES2015で導入されたJavaScriptをモジュールとして実行するための実行コンテキストであるModule
がある Script
はデフォルトでstrict mode
ではなく、Module
はデフォルトでstrict mode
コメント
//
は1行のコメント/* */
は複数行のコメント
変数と宣言
- 変数を宣言するキーワードには
var
、let
、const
がある var
は古いキーワードで意図しない動作を作りやすいlet
とconst
はvar
の問題を改善するためにES2015で追加されたlet
は再代入ができ、初期値を指定しない変数も定義できる- 初期値を指定しない場合は
undefined
という値が未定義であることを表す値になる const
は再代入ができないvar
の問題点- 同じ名前の変数を再定義できてしまう
- 変数の巻き上げ
const
は初期化した後でも値を変更できるオブジェクトにも使えるので定数ではない
値の評価と表示
- JavaScriptの多くの実行環境では、ConsoleAPIを使ってコンソールに表示する
console.log
はデバッグとして使える- エラーには構文エラーと実行時エラー(ランタイムエラー)の2種類ある
- 実行時エラーは実行するまでエラーになるかわからないので、エラーの原因を探るデバッグを行う必要がある
データ型とリテラル
- JavaScriptのデータ型にはプリミティブ型(基本型)とオブジェクトの2つに分類される
- プリミティブ型は一度作成したらその値自体を変更できないイミュータブルという特性を持つ
- オブジェクト型は一度作成した後もその値自体を変更できるミュータブルという特性を持つ
- プリミティブ型は7つある
- 真偽値
- 数値
- 巨大な整数
- 文字列
- undefined
- null
- シンボル
- プリミティブ型ではないものオブジェクト型になる
- データ型の値を直接記述できるように構文として定義されたものがリテラル
- undefinedはリテラルではなくただのグローバル変数で
undefined
という値を持っているだけ - オブジェクトリテラルは
{}
で新しいオブジェクト作成できる - プリミティブ型のデータでもオブジェクトのように参照できる仕組みがあるため、ラッパーオブジェクトを明示的に使う必要はない
演算子
- 任意の数値を0で除算した結果は、無限大を表す数値である
Infinity
となる NaN
はNot-a-Number
の略称で、数値ではないがNumber型の値になる===
は同じ型で同じ値である場合にtrueを返す、オブジェクトの場合は参照が同じである場合にtrueを返す==
は同じ型で同じ値である場合にtrueを返すが、異なる型の値であった場合、同じ型になるように暗黙的な型変換をしてから比較するので、意図しない挙動が発生する可能性がある- 例外的に
null
とundefined
の比較のために==
が使われることがある - 配列やオブジェクトの値を複数の変数に同時に代入できるのが分割代入
- 暗黙的にfalseに変換される値
- false
- undefined
- null
- 0
- 0n
- NaN
- ""
- AND演算子で左辺がfalseの場合、右辺は評価されない、このことを短絡評価という
- OR演算子は左辺がtrueの場合、右辺は評価されない
- 評価結果がnullまたはundefinedとなる値を
nullish
という - カンマで区切った式は左から順に評価される
暗黙的な型変換
- 暗黙的な型変換はバグの原因となるので、型変換をしたい場合は明示的にする
- Booleanコンストラクタで真偽値に変換できる
- Stringコンストラクタで数値から文字列に変換できる
- シンボルは暗黙的な型変換ができない
- Numberコンストラクタで文字列から数値に変換できる
- NaNは何と演算してもNaNになり、デバッグが難しくなるので避けるべき
関数と宣言
return
の値を省略、またはreturn
そのものを省略した場合はundefined
が返される- 仮引数と呼び出し時の引数の数が違っても関数を呼び出せる
- 呼び出し時の引数が少ない場合、余った仮引数には
undefined
が代入される - ES2015からはデフォルトで引数を代入できるデフォルト引数を指定できる
- 呼び出し時の引数が多い場合は、溢れた引数は無視される
- 引数が固定ではなく、任意の個数の引数を受け取るものを可変長引数という
- 可変長引数を実現するには、
Rest parameters
かarguments
を使う - ES2015から追加されたRest parametersは関数に渡された値が配列として代入される可変長引数
arguments
は関数の中でのみ参照できる特殊な変数で、渡された引数の値が全て入っている配列のようなオブジェクトRest parametes
を使えるならarguments
は使わない- 関数はオブジェクトの一種で、
()
をつけると処理を呼び出せて、()
をつけないとオブジェクトとして参照できる - 関数をあたいとして変数へ代入したものを関数式という
- 関数宣言は文で、関数式は値として扱う
- 関数式で名前を持たない関数を代入したものを無名関数という
- ES2015では無名関数を
=>
を使ってArrow Funtionで書ける this
の挙動やarguments
を使えないなどの解釈や実装による違いが生まれにくい特徴から、基本的にはArrow Functionを使い、そうでない場合はFunctionを使う- 関数の引数として渡された関数をコールバック関数という
- コールバック関数はいちいち定義するのは面倒なので、無名関数として使うことが多い
- コールバック関数を引数として使う関数を高階関数という
- コールバック関数は非同期処理でよく使われる
文と式
- JavaScriptは文と式から構成される
- 式は値を生成し、変数に代入できるもの
- 文は処理する1ステップのことで、変数に代入できない
{}
で囲んだ部分をブロックという- if文などと組み合わせずに単独のブロック文を書くことはほとんどない
条件分岐
- 1行のif文はブロックを省略できるがわかりづらいので常にブロックで囲むことが推奨される
- switch文の式は
===
で評価される - switch文はif文の代用より、関数と組み合わせて条件に対する値を返すパターンとして使われることが多い
ループと反復処理
- while文は他により安全な反復処理の書き方があるので、使う場面は限られる
- do-while文は条件がfalseでも最初に処理が実行される
- 配列のforEachメソッドは条件式がなく、配列の全ての要素を反復処理する
- for...in文はオブジェクトのプロパティに対して反復処理を行う
- for...in文は親オブジェクトのプロパティまで列挙可能なものを探すので、意図しない結果になる場合がある
- ES2015で追加されたfor...of文は反復処理時の動作が定義されたオブジェクトの総称であるiterableオブジェクトを反復処理できる
- Array、String、Map、Setなどはiterableオブジェクト
- for文などの構文はcontinue文やbreak文を使える
- 配列のメソッドでは一時的な変数が必要なかったり、処理をコールバック関数として書く
オブジェクト
- JavaScriptでは
Object
というどの実行環境でも使えるビルトインオブジェクトが定義されている {}
はObject
のインスタンスオブジェクトになる- new演算子でもインスタンスを作成できるが、簡潔な
{}
を使うべき - プロパティの参照では基本的に
.
を使い、変数を指定したい場合は[]
を使う - オブジェクトはミュータブルの特性を持つ
- オブジェクトの初期化時以外にプロパティを追加するとどんなプロパティを持つか分かりにくくなるので、オブジェクト作成時に定義する
- 存在しないプロパティにアクセスすると、例外ではなく
undefined
が返される - プロパティの存在を確認するにはin演算子か、
Object.hasOwn
静的メソッドを使う - オブジェクトのプロパティにアクセスするとプロパティ名は暗黙的に文字列に変換される
Object.assing
メソッドを使うと、オブジェクトのマージや複製ができる
プロトタイプオブジェクト
- オブジェクトに組み込まれたメソッドをビルトインメソッドという
- ほとんどすべてのオブジェクトは
Object.prototype
プロパティに定義されたprototoype
オブジェクトを継承している prototype
はすべてのオブジェクトの作成時に自動的に追加される、すべてのオブジェクトから利用できるメソッドなどを提供する特殊なオブジェクトprototype
オブジェクトに組み込まれているメソッドをプロトタイプメソッドという- インスタンスからプロトタイプメソッドを呼び出せることをプロトタイプチェーンという
- 同じ名前のプロトタイプメソッドとインスタンスメソッドはインスタンスメソッドが優先して呼び出される
Array
もArray.prototype
をもつObject.create(null)
でプロトタイプオブジェクトを継承しない完全に空のオブジェクトを作れる
配列
- JavaScriptにおける配列は可変長
- 存在しないインデックスに対してアクセスすると
undefined
を返す - 配列には未定義の値を持つ要素を含むことができる
- 配列から要素を検索する目的
- インデックスを取得する
- 要素自体を取得する
- 要素が存在するかの真偽値を取得する
- 配列の要素の追加、削除
- 末尾に追加 - push
- 末尾を削除 - pop
- 先頭に追加 - unshift
- 先頭を削除 - shift
- 任意のインデックスの要素を削除 - Array.prototype.slice
- ES2015で追加されたSpread構文を使うことで、配列の中に既存の配列を展開できる
- 破壊的なメソッドは配列オブジェクトそのものを変更し、非破壊的なメソッドは配列オブジェクトのコピーを作成してから変更する
- 反復処理の中でよく使われるメソッド
- forEach - 反復処理
- map - 反復処理を行なって新しい配列を返す
- filter - 反復処理を行いtrueを返した要素だけの新しい配列を返す
- reduce - 反復処理を行い、累積値を返す(可読性がよくない)
- 配列のメソッドはメソッドチェーンといって繋げて実行でき、複数の処理をまとめることができる
文字列
- JavaScriptは文字コードにUnicodeを採用し、文字をエンコードする方式としてUTF-16を採用している
- UTF-16はそれぞれの文字を16ビットのビット列に変換するエンコード方式
- 1文字を表すのに使う最小限のビットの組み合わせをCode Unitという
- つまり、JavaScriptにおける文字列は16ビットのCode Unitが順番に並んだものとして内部的に管理されている
- 文字列の厳密比較は以下の条件を満たしていれば同じ文字列となる
- Code Unitが同じ順番で並んでいるか
- 文字列の長さが同じか
- 正規表現リテラルはソースコードをパースした段階で評価され、
RegExp
コンストラクタは通常の関数と同じように呼び出した時に評価される - 正規表現リテラルの方が簡潔でパフォーマンスがいいが、変数を使いたい時などは
RegExp
コンストラクタを使う - URLなどの構造的な文字列を扱う場合は専用の関数を使うべき
文字列とUnicode
- UTF-16を採用するのはJavaScriptの内部であり、ファイルの文字コードは他の文字コードでも問題ない
- Unicodeにおける文字に対する一意のIDをCode Pointという
- Code UnitやCode Pointを意識しなくても文字列の処理はできるが、絵文字を使うときはCode Pointを意識する必要がある
ラッパーオブジェクト
- 真偽値、数値、BigInt、文字列、シンボルにはそれぞれ対応するオブジェクトがあり、それらをラッパーオブジェクトという
- プリミティブ型の値に対してプロパティアクセスする時、自動で対応するラッパーオブジェクトに変換される
- ラッパーオブジェクトではなくリテラルを使うべき
- JavaScriptは全てがオブジェクトであるわけではなく、すべてがオブジェクトのように見えるというのが正しい
関数とスコープ
- 関数は変数や関数の引数などを参照できる範囲であるスコープを持つ
- スコープの中で定義された変数はスコープの外からは参照できない
- 関数の仮引数はスコープに紐づけられる
- 関数によるスコープを関数スコープという
{}
で囲まれた範囲をブロックスコープという- for文はループごとに新しいブロックスコープを作成した
- スコープはネストでき、内側のスコープから外側のスコープにある変数は参照できる
- 内側から外側のスコープへ順番に変数を探すことをスコープチェーンという
- もっとも外側のスコープをグローバルスコープといい、グローバルスコープにある変数をグローバル変数という
- むやみにグローバル変数を定義しない
- 変数を参照できる範囲をできるだけ小さくする
let
は変数を宣言する前に参照するとエラーになるが、var
はundefined
になるのでエラーにならない → 変数の巻き上げvar
はブロックスコープを無視する- functionキーワードを使った関数宣言も宣言より前に呼び出せる巻き上げが起こる
let
とconst
が追加されるまでは、関数スコープを作ってグローバルスコープの汚染を避けるために即時実行関数を使われていた- どの識別子がどの変数を参照しているかを静的に決定する性質を静的スコープといい、JavaScriptの変数や関数の参照先は静的スコープで決まる
- JavaScriptには参照されなくなった不要なデータをメモリから解放するガベージコレクションという仕組みがある
- 静的スコープとメモリ管理の仕組みによって、関数内から特定の変数を参照し続けることで関数が状態を持てる仕組みのことをクロージャーという
- 関数はオブジェクトであるためプロパティに状態を持たせることもできるが、関数の外からプロパティを変更できるため推奨されない
- クロージャーはグローバルスコープの汚染を防いだり、関数に状態を持たせるために使う
関数とthis
this
は読み取り専用のグローバル変数のようなもので、条件によって参照先が異なるthis
が実際に使われるのはメソッドで、メソッド以外では使うべきではない- 実行コンテキストにおける
this
- 最も外側のスコープでは実行コンテキストによって
this
の参照先は変わるので、使うべきではない - スクリプトにおける
this
の参照先 → グローバルオブジェクト(実行環境ごとに異なる) - モジュールにおける
this
の参照先 →undefined
- 最も外側のスコープでは実行コンテキストによって
- 関数とメソッドにおける
this
- Arrow Function以外の関数における
this
- 関数宣言、関数式における
this
の参照先 →undefined
- メソッド呼び出しにおける
this
の参照先 → ベースオブジェクト
- 関数宣言、関数式における
- strict modeではないと
this
がundefined
の場合、グローバルオブジェクトを参照するように変換されてしまう - Arrow Functionにおける
this
- Arrow Functionは
this
をもてない - 参照先 → 外側のスコープの
this
- Arrow Functionは
- Arrow Function以外の関数における
this
は定義したときではなく実行時に決定されるので、関数にthis
が含まれていると意図しない結果が発生する場合がある- 対策
- メソッドは関数ではなくメソッドとして呼ぶ
call
、apply
、bind
メソッドを使って明示的にthis
を指定する
- 対策
- 明示的に
this
を指定することで、本来undefined
となる部分にオブジェクトを渡すことができる call
とapply
の違いは引数への値の渡し方が異なるbind
はthis
が束縛された関数を作る- コールバック関数はただの関数として呼ばれベースオブジェクトがないので、
this
はundefined
になる- 対策
this
をthat
のような一時変数に代入する- Arrow Functionでコールバック関数を使う(ES2015からはこっちの方が簡潔)
- 対策
クラス
- JavaScriptではES2015まではクラスがなく関数を使ってクラスのようなものを表現していた → 書き方を統一するためにES2015でclass構文が導入される
- class構文はプロトタイプベースの継承の仕組みを使って関数でクラスを表現している
- クラスは必ずコンストラクタを持つ
- クラスは関数式のように値として定義できる
- コンストラクタ内での
this
はインスタンスのオブジェクトを参照する new
演算子でインスタンスが返されることが期待されるため、コンストラクタでreturn
文を使って任意のオブジェクトを返すべきではない- 関数で表現したクラスは関数として呼び出せるが、class構文で定義したクラスは関数として呼び出すことはできない
- インスタンス間で共有されるメソッドをプロトタイプメソッドという
- 外から読み書きして欲しくないプロパティには
_
をつける慣習がある - 外からアクセスできるプロパティをPublicクラスフィールド、外からアクセスできないプロパティをPrivateクラスフィールド
- 静的メソッドには
static
をつける - 静的メソッド内の
this
はクラス自身を参照する - プロトタイプメソッドはプロトタイプオブジェクトに、インスタンスオブジェクトのメソッドはインスタンスオブジェクトに定義されるので、同時に定義しても上書きされない
- インスタンスオブジェクトのメソッドがプロトタイプメソッドより優先して呼び出される
- classも関数オブジェクトの1種であるため、自動的に
prototype
プロパティにプロトタイプオブジェクトが作成される - class構文のメソッド定義はプロトタイプオブジェクトのプロパティとして定義される
- インスタンスにメソッドを定義していなくても、インスタンスの生成時にクラスのプロトタイプオブジェクトへの参照が保存されるので、プロトタイプチェーンによってインスタンスからクラスのプロトタイプメソッドを呼び出せる
- インスタンスはどのクラスから作られたかと、そのプロトタイプオブジェクトを知っている
- オブジェクトがプロパティを探す時は、まずインスタンス自身から探し、次に
[[Prototype]]
の参照先を探し、どこにも無かったらundefined
を返す super()
で子クラスから親クラスのconstructor
を呼び出せる- コンストラクタは親クラスから実行される
- ビルトインオブジェクトも継承できる
例外処理
try
の中で例外が発生するとcatch
の処理が実行されるfinally
の処理は必ずtry
の最後に実行されるthrow
で例外を投げることができる- デバッグに役立つスタックトレースを得るために、例外は
Error
オブジェクトのインスタンスを投げるべき - ビルトインエラーの種類
- ReferenceError - 存在しない変数や関数が参照された時のエラー
- SyntaxError - 構文エラー
- TypeError - 値が期待される型ではない場合のエラー
- エラーに関するログ出力は
console.error
を使う
非同期処理:Promise/Async Function
- コードをを順番に1つずつ実行する処理を同期処理という
- 同期処理では現在の処理が終わるまで次の処理に進めない
- JavaScriptの処理はブラウザのメインスレッドで実行される
- メインスレッドはUIに関する処理も行われるため、他の処理が実行されると表示が更新されなくなる
- 同期処理とは反対に処理の終了を待たずに次の処理を実行するものを非同期処理という
- 非同期処理も大部分はメインスレッドで実行される
- 非同期処理は処理を一定の単位ごとに分けて切り替えながら実行する並行処理として扱われる
- 実行環境によってメインスレッドとは別のスレッドで実行できるものもある
- 非同期処理では例外をキャッチできない
- 非同意処理の外からは非同期処理の中で例外が発生したかわからないため、例外が発生したことを非同期処理の中から外に伝える方法が必要
Promise
- PromiseはES2015で導入された非同期処理の状態や結果を表現するビルトインオブジェクト
- 非同期処理が成功すれば
resolve()
を呼び、失敗すればreject()
を呼び出す - 成功時のコールバック関数は
then
メソッドで登録し、失敗時のエラー処理はthen
ではなくcatch
メソッドを使う - Promiseではコンストラクタの処理で例外が発生した場合には自動的に例外がキャッチされ、
then
やcatch
で登録したエラー時のコールバック関数が呼び出される - Promiseのインスタンスには3つの状態がある
- Fulfilled - 成功
- Rejected - 失敗または例外発生
- Pending - インスタンスを作成した時の初期状態
- 複数の非同期処理を順番に扱いたい場合はPromiseをメソッドチェーンでつなぐPromiseチェーンを使う
- 成功時、失敗時のどちらの場合でも呼び出したい処理は
finally
メソッドに書く
Async Function
- Async FunctionはES2017で追加された非同期処理を行う関数を定義する構文で、Promiseの上に作られている
- Async Functionは関数の前に
async
をつけ、必ずPromiseインスタンスを返す await
を使うことで、Promiseチェーンの可読性を解決し、非同期処理を同期処理のように扱えるawait
は右辺のPromiseインスタンスがFulfilledまたはRejectedになるまで非同期処理の完了を待ち、Promiseの状態が変わると次の行の処理を再開するawait
はPromiseがRejectedになった場合に例外をキャッチするawait
はAsync Functionの直下でのみ使える
Map/Set
- MapとSetはES2015で追加されたデータの集まりであるコレクションを扱うビルトインオブジェクト
Map
- Mapはキーと値の組み合わせであるマップを扱うためのビルトインオブジェクト
new
で新しいMapオブジェクトを作成する- コンストラクタにキーと値の配列を初期値として渡すことができる
- ObjectをMapとして使うメリット
- Mapを使うメリット
- プロトタイプのメソッドやプロパティとキーが衝突しない
- キーにはあらゆるオブジェクトを使える
- マップのサイズを簡単に知ることができる
- 要素を簡単に列挙できる
Set
- Setは重複する値がないことを保証したコレクション
- 要素は順序とインデックスを持たない
new
で新しいSetオブジェクトを作成する- 重複する値は無視される
JSON
- JSONはオブジェクトリテラル、配列リテラル、各種プリミティブ型の値を組み合わせたもの
- JSONではオブジェクトのキーを必ずダブルクォートで囲まなければならない
JSON.parse
メソッドで、JSONの文字列をオブジェクトに変換できる- 実際のアプリでJSONを扱うのは外部のプログラムとデータを交換する用途がほとんど
- 外部のプログラムが送ってくるデータが常にJSONとは限らないため、常に例外処理をすべき
JSON.stringify
メソッドで、オブジェクトをJSONの文字列に変換できる
Date
Math
ECMAScriptモジュール
- モジュールとは変数や関数などをまとめたJavaScriptの1ファイル
- モジュールは依存性の高いコードをまとめて、再利用するために使う
- モジュールを外部から使えるようにすることをエクスポート、モジュールを読み込むことをインポートという
- エクスポート・インポートそれぞれに名前付きとデフォルトの2種類ある
- 名前付きにはエイリアスを使って違う名前でエクスポート/インポートできる
- デフォルトエクスポートはモジュールごとに1つしかエクスポートできない特殊なエクスポート
- 関数は宣言と同時にエクスポートできるが、変数はできない
- デフォルトインポートはデフォルトエクスポートに名前をつけてインポートする
import * as
で全ての名前付きエクスポートをまとめてインポートでき、モジュールごとの名前空間となるオブジェクトを宣言し、そのプロパティを使ってアクセスする- ファイルをモジュールとして読み込むには
script
タグのtype
属性をmodule
とする(指定しない場合構文エラーとなる)
- ファイルをモジュールとして読み込むには
第二部 応用編
- Node.jsはJavaScript実行環境のひとつで、V8JavaScriptエンジンで動作する
- Node.jsにはnpmというパッケージマネージャーが同梱されている
npm
コマンドではなく、npx
コマンドを使うとnpmで公開されている実行可能なパッケージのインストールと実行をまとめてできる
Ajax
- HTMLのコンテンツと構造をJavaScriptから操作できるオブジェクトをDOMといい、動的なWebアプリを作るためには不可欠
- DOMはブラウザが実装しているAPIで、HTMLをブラウザで読み込む時に生成され、HTMLのタグと入れ子構造を木構造で表現する
- Fetch APIを使うことで、ページを再読み込みすることなくHTTP通信を行い指定したURLからデータを取得できる
- JavaScriptでHTML要素をDOMに追加する方法は2つある
- HTML文字列を
innerHTML
プロパティにセットする Element
オブジェクトを生成して手続き的にツリー構造を構築する
- HTML文字列を
- HTMLのエスケープはライブラリで行うのが一般的
- バッククォートの前に関数を書くとタグ関数として呼び出せる
Node.jsでCLIアプリ
- Node.js環境では
console.log
の出力先は標準出力になる - JavaScriptのコードをNode.jsで実行するには
node
コマンドを使う - Node.jsではエントリーポイントとなるJavaScriptファイルを作成し、そのファイルを
node
コマンドの引数に渡して実行するのが基本 - Node.jsのグローバルオブジェクトは
global
オブジェクト - Node.jsの実行プロセスの情報の取得と操作ができる
process
のargv
というグローバル変数のプロパティによってコマンドラインの引数にアクセスできる - アプリでコマンドライン引数を扱うときは一度パースして扱いやすい値に整形するのが一般的
- ECMAScriptモジュールの前はCommonJSモジュールが使われていて、相互運用性に注意する
- Node.jsでファイルの読み書きを行うには
fs
モジュールを使う
Todoアプリ
- JavaScriptから扱うid属性は慣習的に
js-
からはじめる名前にする - イベントの発生を元に処理を進めることをイベント駆動(イベントドリブン)という
- 直接DOMを更新する問題
- 状態をすべてHTMLに埋め込み、文字列として扱わなければならない
- 更新箇所が増えると操作に対する処理が複雑になる
- 直接DOMを更新する問題を解決するにはモデルを使って状態を管理する
- 表示は操作ではなくモデルが変化したタイミングで更新する
- 状態が変化したらイベントを発生させる
- イベントはディスパッチとリスナーによって成り立つ
開発を補助するツール
- Babelは古いブラウザにも対応させるために、新しい構文を古い構文に変換するツール
- TypeScriptはJavaScriptに静的型づけの構文を追加した言語
- モジュールバンドラーはJavaScriptのモジュール依存関係を解決し、複数のモジュールを1つのJavaScriptファイルに結合するツールで、webpackがよく使われる