Skip to content

Commit f1d5cf1

Browse files
committed
ハンドルできないエラー表示
1 parent eba976b commit f1d5cf1

17 files changed

+898
-164
lines changed

console.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
console.log({name});
7272
>>> { "name": "wozozo" }
7373
74+
.. note::
75+
76+
2020年9月リリースのChrome 85から挙動が変わり、コンソールの左にあるログレベルを選択した場合、選択したものだけが表示されます。エラーがあった場合にもerrorを選択しなければ表示されません。Chrome 84以前、および2020年10月現在のSafariでは選択したログレベル以上のものが表示されますので、infoやwarnを選択した場合にもエラーが表示されます。
7477

7578
``console.table/dir()``
7679
--------------------------------

docs/_images/consoleerror.png

357 KB
Loading

docs/_images/unhandleexception.png

436 KB
Loading

docs/_sources/console.rst.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
console.log({name});
7272
>>> { "name": "wozozo" }
7373
74+
.. note::
75+
76+
2020年9月リリースのChrome 85から挙動が変わり、コンソールの左にあるログレベルを選択した場合、選択したものだけが表示されます。エラーがあった場合にもerrorを選択しなければ表示されません。Chrome 84以前、および2020年10月現在のSafariでは選択したログレベル以上のものが表示されますので、infoやwarnを選択した場合にもエラーが表示されます。
7477

7578
``console.table/dir()``
7679
--------------------------------

docs/_sources/exception.rst.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,27 @@ JavaScriptの言語の標準に含まれていない、処理系独自の機能
360360

361361
Node.jsで ``async`` / ``await`` やら ``Promise`` を一切使っていないコードの場合、エラーを無視すると、Node.js自体が最後に ``catch`` して、エラー詳細を表示してプログラムが終了します。これはある意味プログラムとしては作戦放棄ではありますが、「プログラムの進行が不可能なので、OSに処理を返す」というリカバリーと言えなくもないでしょう。開発者にスタックトレースを表示して後を託す、というのも立派なリカバリーの戦術の1つです。
362362

363-
ブラウザの場合、誰もキャッチしないと、開発者ツールのコンソールに表示されますが、開発者ツールを開いていない限りエラーを見ることはできません。ユーザーには正常に正常に処理が進んだのか、そうじゃなかったのかわかりませんので、かならずキャッチして画面に表示してあげる必要があるでしょう。
363+
ブラウザの場合、誰もキャッチしないと、開発者ツールのコンソールに表示されますが、開発者ツールを開いていない限りエラーを見ることはできません。普段から開発者コンソールを開いている人はまれだと思いますし、大部分のユーザーには正常に正常に処理が進んだのか、そうでなかったのかわかりませんので、かならずキャッチして画面に表示してあげる必要があるでしょう。
364364

365365
どちらにしても何かしらのリカバリー処理が必要となりますので、本書ではエラーと例外の区別といったことはしません。
366366

367+
例外処理のハンドリングの漏れ
368+
-------------------------------------------------------
369+
370+
例外処理が漏れた場合、ロジックが中断します。例えば、サーバー通信結果のJSONのパースでエラーが発生すると、\ ``SyntaxError``\ が発生し、その後の処理が行われなくなります。そのJSONをパースして画面に表示しようとしていた場合は、通信は行われるものの、画面表示が更新されずに何も発生していないように見えます。この場合、開発者ツールをみると、\ ``Uncaught Error``\ が記録されています。なお、将来のNode.jsではエラーコード0以外で、プログラムが終了することになっています。
371+
372+
.. figure:: images/exception/unhandleexception.png
373+
374+
キャッチしていない例外
375+
376+
一方、やっかいなのが、サーバー通信のエラーです。XMLHttpRequestの場合は\ ``onerror()``\ コールバックでエラーを取得してハンドルする必要がありますが、うまくハンドルしてもコンソールにはエラーが残ります。fetchの場合は\ ``Uncaught (in promise) Error``\ が出ますが、これを適切に処理しても、やはり同様のエラーが出力されます。
377+
378+
これは\ :doc:`console`\ の章で紹介した\ ``console.error()``\ 出力と同じです。うまくハンドリングしても、キャッチしなかったときと同じように赤くエラーが表示されます。XHRを直接使う場合は\ ``onerror``\ が設定されていなくて例外が握り潰されている可能性もゼロではないため注意しなければなりませんが、XHRをラップした\ `axios <https://www.npmjs.com/package/axios>`_\ や、\ ``fetch()``\ を使った場合には\ ``Uncaught Error``\ の文字がなければ実装上は気にする必要はありません。
379+
380+
.. figure:: images/exception/consoleerror.png
381+
382+
うまく処理できていた場合にも同様に表示されるエラー
383+
367384
例外処理機構以外で例外を扱う
368385
--------------------------------------
369386

docs/_sources/function.rst.txt

Lines changed: 107 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,48 @@
11
関数
22
==================
33

4-
関数の定義、使い方などもいろいろ変わりました。表現したい機能のために、ややこしい直感的でないコードを書く必要性がかなり減っています
4+
関数は一連の処理に名前をつけてまとめたものです。他の人の作ったものを利用するだけでは関数などなくても、必要な処理を必要なだけ列挙すれば期待する結果が得られるコードは理論上は実現可能です。しかし、数万行の一連のコードを扱うのは事実上不可能です
55

6-
アロー関数
7-
----------------------
6+
そこで理解できる大きさにグループ化して、名前をつけたものが関数です。関数呼び出しはネストできるので、難しいロジックに名前をつけて関数を作り、それらのロジックを並べたちょっと複雑なタスクを人間の仕事に近い高水準な関数にできます。関数は決まった処理を単純に実行するだけではなく、引数をとって、柔軟に動作させることもできますし、返り値を返すこともできます。
87

9-
JavaScriptでは、やっかいなのが\ ``this``\ です。無名関数をコールバック関数に渡そうとすると、\ ``this``\ がわからなくなってしまう問題があります。
10-
アロー関数を使うと、その関数が定義された場所の\ ``this``\ の保持までセットで行いますので、無名関数の\ ``this``\ 由来の問題をかなり軽減できます。
11-
表記も短いため、コードの幅も短くなり、コールバックを多用するところで ``function`` という長いキーワードが頻出するのを減らすことができます。
8+
どの程度の分量が適切かはロジックの複雑さによります。単純な仕事を延々と行っている(Reactのコンポーネントのレンダリングなど)であれば、数画面分のコードでもなんとかなるでしょうし、帰って細かく分け過ぎてしまうと、全体像の把握が難しくなります。一方で複雑なロジックだと20行でも難しいかもしれません。
129

13-
.. code-block:: ts
14-
:caption: アロー関数
10+
関数の基本形態は以下の通りです。
1511

16-
// アロー関数ならその外のthisが維持される
17-
this.button.addEventListener("click", () => {
18-
this.smallAnimal.walkTo("タコ公園");
19-
});
12+
* 関数は名前を持ちます。何かに代入したり、引数で渡す場合は省略可能です
13+
* 引数はカンマ区切りで名前と型を列挙していきます。引数がない場合は省略可能です。引数の型はジェネリクスを使って省略可能にもできますが、基本的に指定が必要です。
14+
* 返り値はreturnで返します。返り値がない場合は\ ``return``\ を省略可能です。
15+
* もしreturn文の数が一つ、または複数個あっても、毎回同じ型を返しているのであればreturnの型は省略可能です。
2016

21-
アロー関数にはいくつかの記法があります。
22-
引数が1つの場合は引数のカッコを、式の結果をそのまま ``return`` する場合は式のカッコを省略できます。
23-
ただし、引数の場所に型をつけたい場合は省略するとエラーになります。
17+
.. code-block::
2418
25-
.. code-block:: ts
26-
:caption: アロー関数の表記方法のバリエーション
19+
function 関数名(引数リスト): 返り値の型 {
20+
return 返り値
21+
}
2722
28-
// 基本形
29-
(arg1, arg2) => { /* 式 */ };
23+
TypeScriptの関数には次のような特徴があります。
3024

31-
// 引数が1つの場合は引数のカッコを省略できる
32-
// ただし型を書くとエラーになる
33-
arg1 => { /* 式 */ };
25+
* 関数そのものを変数に入れて名前をつけられるし、データ構造にも組み込める
26+
* 他の関数の引数に関数を渡せる
27+
* 関数の返り値として返すことができる
3428

35-
// 引数が0の場合はカッコが必要
36-
() => { /* 式 */ };
29+
関数を受け取る関数があると、プログラムの柔軟性が飛躍的に高まります。従来のJavaScriptは関数の使い勝手が極めて便利だった一方で、言語の他の機能は少なく、関数を多用した数々のテクニックが生み出されました。一方で、かなり黒魔術な、一見すると魔法のような使われ方も多数ありました。近年ではECMAScriptやTypeScriptのバージョンアップで数多くの機能が増え、トリッキーな使い方はだいぶ減っていますが、重要なことには変わりません。
3730

38-
// 式の { } を省略すると、式の結果が return される
39-
arg => arg * 2;
31+
関数にはいくつかのバリエーションがあります。
4032

41-
// { } をつける場合は、値を返すときは return を書かなければならない
42-
arg => {
43-
return arg * 2;
44-
};
33+
* 名前がない関数は無名関数、あるいはアノニマス関数と呼びます。変数に代入したり、他の関数の引数に渡す場所で利用されます。とくに、関数の内部で作られる関数を「クロージャ」と呼びます。
34+
* 何かのオブジェクトに属する関数は「メソッド」と呼びます。
35+
* 時間のかかる処理を行い、それが終わるまで他のタスクを途中で行える関数を非同期関数と呼びます(\ :doc:`async`\ の章で扱います)
4536

46-
以前は、 ``this`` がなくなってしまうため、 ``bind()`` を使って束縛したり、別の名前(ここでは ``self`` )に退避する必要がありました。
47-
そのため、``var self = this;``と他の変数に退避するコードがバッドノウハウとして有名でした。
37+
名前のない無名関数にはアロー演算子を使った省略記法も追加されました。ふつうの\ ``function``\ キーワードを使った宣言とほぼ同等で置き換えできることが多いのですが、動作については少し異なる部分もあります。こちらについても順をおって説明します。
4838

49-
.. code-block:: ts
50-
:caption: this消失を避ける古い書き方
39+
.. code-block::
5140
52-
// 旧: 無名関数のイベントハンドラではその関数が宣言されたところのthisにアクセスできない
53-
var self=this;
54-
this.button.addEventListener("click", function() {
55-
self.smallAnimal.walkTo("タコ公園");
56-
});
41+
const f = (引数リスト) => {
42+
return 返り値
43+
}
5744
58-
// 旧: bind()で現在のthisに強制束縛
59-
this.button.addEventListener("click", (function() {
60-
this.smallAnimal.walkTo("タコ公園");
61-
}).bind(this));
45+
関数はTypeScriptの中では、プログラムの構成をつくるための重要な部品です。いたるところで使われます。言語のバージョンアップとともに、定義、使い方などもいろいろ追加されました。表現したい機能のために、ややこしい直感的でないコードを書く必要性がかなり減っています。
6246

6347
関数の引数と返り値の型定義
6448
----------------------------------
@@ -292,6 +276,85 @@ setter/getterの宣言も簡単に行えるようになりました。
292276
}
293277
};
294278
279+
280+
クロージャと\ ``this``\ とアロー関数
281+
----------------------------------------------
282+
283+
関数の中で関数を定義したときに、関数は自分の定義の外にある変数を参照できます。
284+
285+
.. code-block::
286+
287+
function a() {
288+
const b = 10;
289+
function c() {
290+
console.log({b}); // bが表示される
291+
}
292+
c();
293+
}
294+
295+
実行時の親子関係ではなく、ソースコードという定義時の親子関係を元にしてスコープが決定されます。これをレキシカルスコープと呼びます。また、このように自分が定義された場所の外の変数を束縛した関数を「クロージャ」と呼びます。TypeScriptでは関数を駆使してロジックを組み上げていきますので、この機能はとても重要です。
296+
297+
以前はJavaのようなオブジェクトを実装するために、関数内部の変数をプライベートメンバー変数のように扱うテクニックがかつてありました。クラスの機能が公式のサポートされたので、今では重要度は低くなっているし、そもそも隠す必要性もあまりなので使うことはありませんが、頭の体操にはなるので、興味がある方は調べてみてください。
298+
299+
レキシカルスコープは今では多くの言語が持っている機能なので、わざわざ名前を呼ぶこともありませんが、TypeScriptでは、知らないと落とし穴に落ちる可能性のあるやや重要な機能となります。前項でオブジェクトの中の関数定義を紹介しました。ここでは、予め定義された変数のように\ ``this``\ を使っています。しかしこれは変数ではなく、特別な識別子です。レキシカルスコープで束縛できません。クロージャかつ、\ ``this``\ への束縛ができる新文法としてアロー関数が追加されました。
300+
301+
アロー関数
302+
~~~~~~~~~~~~~~~~~~~~~~~
303+
304+
JavaScriptでは、やっかいなのが\ ``this``\ です。無名関数をコールバック関数に渡そうとすると、\ ``this``\ がわからなくなってしまう問題があります。
305+
アロー関数を使うと、その関数が定義された場所の\ ``this``\ の保持までセットで行いますので、無名関数の\ ``this``\ 由来の問題をかなり軽減できます。
306+
表記も短いため、コードの幅も短くなり、コールバックを多用するところで ``function`` という長いキーワードが頻出するのを減らすことができます。
307+
308+
.. code-block:: ts
309+
:caption: アロー関数
310+
311+
// アロー関数ならその外のthisが維持される。
312+
this.button.addEventListener("click", () => {
313+
this.smallAnimal.walkTo("タコ公園");
314+
});
315+
316+
アロー関数にはいくつかの記法があります。
317+
引数が1つの場合は引数のカッコを、式の結果をそのまま ``return`` する場合は式のカッコを省略できます。
318+
ただし、引数の場所に型をつけたい場合は省略するとエラーになります。
319+
320+
.. code-block:: ts
321+
:caption: アロー関数の表記方法のバリエーション
322+
323+
// 基本形
324+
(arg1, arg2) => { /* 式 */ };
325+
326+
// 引数が1つの場合は引数のカッコを省略できる
327+
// ただし型を書くとエラーになる
328+
arg1 => { /* 式 */ };
329+
330+
// 引数が0の場合はカッコが必要
331+
() => { /* 式 */ };
332+
333+
// 式の { } を省略すると、式の結果が return される
334+
arg => arg * 2;
335+
336+
// { } をつける場合は、値を返すときは return を書かなければならない
337+
arg => {
338+
return arg * 2;
339+
};
340+
341+
以前は、 ``this`` がなくなってしまうため、 ``bind()`` を使って束縛したり、別の名前(ここでは ``self`` )に退避する必要がありました。
342+
そのため、``var self = this;``と他の変数に退避するコードがバッドノウハウとして有名でした。
343+
344+
.. code-block:: ts
345+
:caption: this消失を避ける古い書き方
346+
347+
// 旧: 無名関数のイベントハンドラではその関数が宣言されたところのthisにアクセスできない
348+
var self=this;
349+
this.button.addEventListener("click", function() {
350+
self.smallAnimal.walkTo("タコ公園");
351+
});
352+
353+
// 旧: bind()で現在のthisに強制束縛
354+
this.button.addEventListener("click", (function() {
355+
this.smallAnimal.walkTo("タコ公園");
356+
}).bind(this));
357+
295358
``this``\ を操作するコードは書かない(1)
296359
--------------------------------------------------
297360

@@ -370,11 +433,11 @@ setter/getterの宣言も簡単に行えるようになりました。
370433

371434
関数についてさまざまなことを紹介してきました。
372435

373-
* アロー関数
374436
* 関数の引数と返り値の型定義
375437
* 関数を扱う変数の型定義
376438
* デフォルト引数
377439
* 関数を含むオブジェクトの定義方法
440+
* クロージャと\ ``this``\ とアロー関数
378441
* thisを操作するコードは書かない(1)
379442
* 即時実行関数はもう使わない
380443

0 commit comments

Comments
 (0)