4.JavaScript特殊文法

# データ型変換

> 警告: 記事は機械翻訳があるため、学習メモとして保存、学習参考用のみ

## 概要

JavaScriptは、変数にはタイプの制限がありません。

```javascript
var x = y ? 1 : 'a';
```

上記のコードでは、変数`x`別の変数に応じて、それは数値ですか、それとも文字列ですか`y`価値。`y`のために`true`時間、`x`それは数値です。`y`のために`false`時間、`x`それは文字列です。`x`タイプのタイプは、コンピレーション段階ではわかりません。

変数のデータ型は不確かですが、さまざまな演算子が必要です。オペレーターのタイプは期待と一致しません左右になると予想されますが、サイドオペレーターは値である場合は、自動的に値に変換します。

```javascript
'4' - '3' // 1
```

上記のコードでは、2つの文字列が縮小されていますが、結果値は取得されます`1`その理由は、JavaScriptが輸送オペレーターを自動的に価値に変換するためです。

この章では、その前に、データ型を手動で実施する方法を説明します。

## 強制変換

強制変換とは主に使用を指します`Number()`同様に`String()`そして`Boolean()`3つの関数は、さまざまなタイプの値を数字、文字列、またはブール値に手動で変換します。

### number （）

使用`Number`関数は、任意のタイプの値を値に変換できます。

以下は2つのケースで分割されています。1つは元のタイプの値であり、もう1つはパラメーターです。

**（1）プリミティブタイプ値**

元のタイプ値の変換ルールは次のとおりです。

```javascript
// 数值：转换后还是原来的值
Number(324) // 324

// 字符串：如果可以被解析为数值,则转换为相应的数值
Number('324') // 324

// 字符串：如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN

// 空字符串转为0
Number('') // 0

// 布尔值：true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0

// undefined：转成 NaN
Number(undefined) // NaN

// null：转成0
Number(null) // 0
```

`Number`関数は文字列を値に変換します。`parseInt`関数は、1つの文字が値に変換できない限り、はるかに厳格です。`NaN`次に、

```javascript
parseInt('42 cats') // 42
Number('42 cats') // NaN
```

上記のコードでは、`parseInt`文字を1つずつ分析します`Number`関数の関数のタイプ。

加えて、`parseInt`そして`Number`この関数は、ストリングフロントガイドと苦しんでいるスペースを自動的にフィルタリングします。

```javascript
parseInt('\t\v\r12.34\n') // 12
Number('\t\v\r12.34\n') // 12.34
```

**（2）オブジェクト**

簡単なルールは、`Number`メソッドのパラメーターはオブジェクトです、それは返されます`NaN`単一の値を含む配列でない限り。

```javascript
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
```

これが原因である理由は`Number`それらの背後にある変換ルールはより複雑です。

最初のステップは、オブジェクト自体を呼び出すことです`valueOf`方法は、元のタイプの値を返す場合、この値に直接使用します`Number`機能、フォローアップステップなし。

ステップ2、if`valueOf`メソッドの返品はオブジェクト、コールオブジェクト自体です`toString`方法`toString`メソッドは元のタイプの値を返し、この値に使用します`Number`機能、フォローアップステップなし。

ステップ3、if`toString`メソッドはオブジェクトを返し、エラーが報告されます。

以下の例をご覧ください。

```javascript
var obj = {x: 1};
Number(obj) // NaN

// 等同于
if (typeof obj.valueOf() === 'object') {
  Number(obj.toString());
} else {
  Number(obj.valueOf());
}
```

上記のコードでは、`Number`関数`obj`オブジェクトは値に変わります。`obj.valueOf`メソッドは、結果がオブジェクト自体を返します`obj.toString`メソッド、次に文字列を返します`[object Object]`この文字列を使用します`Number`機能、取得`NaN`次に、

デフォルトでは、オブジェクトのものです`valueOf`メソッドはオブジェクト自体を返すため、通常は呼ばれます`toString`方法、および`toString`方法オブジェクトの型文字列（`[object Object]`）。

```javascript
Number({}) // NaN
```

もし`toString`メソッドリターンは元のタイプの値ではなく、結果はエラーを報告します。

```javascript
var obj = {
  valueOf: function () {
    return {};
  },
  toString: function () {
    return {};
  }
};

Number(obj)
// TypeError: Cannot convert object to primitive value
```

その上`valueOf`そして`toString`方法、すべてのオブジェクトが返されるため、エラーが値に変換されると報告されます。

あなたは上記の例から見ることができます、`valueOf`そして`toString`メソッドはカスタマイズできます。

```javascript
Number({
  valueOf: function () {
    return 2;
  }
})
// 2

Number({
  toString: function () {
    return 3;
  }
})
// 3

Number({
  valueOf: function () {
    return 2;
  },
  toString: function () {
    return 3;
  }
})
// 2
```

上記のコードは、3つのオブジェクトに使用されます`Number`最初のオブジェクトが返されます`valueOf`メソッドの値、2番目のオブジェクトが返されます`toString`メソッドの値、3番目のオブジェクトは`valueOf`最初にメソッド`toString`メソッド実行。

### String （）

`String`関数はあらゆるタイプの文字列に変換でき、変換ルールは次のとおりです。

**（1）プリミティブタイプ値**

- **価値**：対応する文字列に変えます。
- **String**：変換後、それはまだ元の値です。
- **ブール値**`true`文字列に頼ります`"true"`、、、、`false`文字列に頼ります`"false"`次に、
- **未定義**：文字列に頼ります`"undefined"`次に、
- **ヌル**：文字列に頼ります`"null"`次に、

```javascript
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
```

**（2）オブジェクト**

`String`メソッドのパラメーターがオブジェクトである場合、文字列のタイプを返します。

```javascript
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
```

`String`メソッドの背後にある変換ルール、および`Number`この方法は基本的に同じですが、交換されます`valueOf`方法と`toString`メソッドの実行順序。

1. 最初にオブジェクト自体を呼び出します`toString`方法は、元のタイプの値を返します。`String`機能、もう次の手順はありません。

2. もし`toString`メソッドはオブジェクトを返し、元のオブジェクトを呼び出します`valueOf`方法`valueOf`メソッドは元のタイプの値を返し、この値に使用します`String`機能、もう次の手順はありません。

3. もし`valueOf`メソッドはオブジェクトを返し、エラーが報告されます。

以下は例です。

```javascript
String({a: 1})
// "[object Object]"

// 等同于
String({a: 1}.toString())
// "[object Object]"
```

上記のコードは、最初にオブジェクトを呼び出します`toString`方法、背面が文字列であることがわかりました`[object Object]`、これ以上電話はありません`valueOf`メソッド。

もし`toString`ダルマ`valueOf`方法、すべてのオブジェクトが返され、エラーが報告されます。

```javascript
var obj = {
  valueOf: function () {
    return {};
  },
  toString: function () {
    return {};
  }
};

String(obj)
// TypeError: Cannot convert object to primitive value
```

以下はカスタムを使用しています`toString`方法、返品値の例を変更します。

```javascript
String({
  toString: function () {
    return 3;
  }
})
// "3"

String({
  valueOf: function () {
    return 2;
  }
})
// "[object Object]"

String({
  valueOf: function () {
    return 2;
  },
  toString: function () {
    return 3;
  }
})
// "3"
```

上記のコードは、3つのオブジェクトに使用されます`String`最初のオブジェクトが返されます`toString`メソッドの値（値3）、2番目のオブジェクトはに返されます`toString`メソッド値（`[object Object]`）、3番目のオブジェクトは表します`toString`最初にメソッド`valueOf`メソッド実行。

### boolean（）

`Boolean()`関数は、あらゆるタイプの値をブール値に変換できます。

その変換ルールは比較的単純です：次の5つの値の変換された結果を除いて`false`、他のすべての値はです`true`次に、

- `undefined`
- `null`
- `0`（含む`-0`そして`+0`。
- `NaN`
- `''`（空の文字列）

```javascript
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
```

確かに、`true`そして`false`これらの2つのブール値は変わりません。

```javascript
Boolean(true) // true
Boolean(false) // false
```

すべてのオブジェクトの変換結果（空のオブジェクトを含む）は`true`平`false`対応するブールオブジェクト`new Boolean(false)`あまりにも`true`（詳細については、「元のタイプ値のパッケージオブジェクト」を参照）。

```javascript
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
```

すべてのオブジェクトのブール値はです`true`これは、JavaScript言語が設計されている場合、ブールを取得するためにオブジェクトを計算する必要がある場合です。`obj1 && obj2`このシーンは、より多くの計算が必要になる場合があります。`true`次に、

## 自動変換

以下は、強制変換に基づいた自動変換を導入します。

次の3つのケースでは、JavaScriptはデータ型を自動的に伝えます。つまり、変換は自動的に完了します。

最初のケースでは、異なるタイプのデータが計算されます。

```javascript
123 + 'abc' // "123abc"
```

2番目のケースは、非ブールタイプのブール値を見つけることです。

```javascript
if ('abc') {
  console.log('hello')
}  // "hello"
```

3番目のケースでは、1つのドラーコンピューティングシンボル（つまり、`+`そして`-`））。

```javascript
+ {foo: 'bar'} // NaN
- [1, 2, 3] // NaN
```

自動変換のルールは次のとおりです。たとえば、特定の場所が文字列になると予想される場合、どのタイプの値が予想されますか。`String()`関数が変換されます。位置が文字列または値になる可能性があります。

自動変換は不確実であり、間違いを削除することは容易ではないため、ブール値、値、文字列であると予想される場合に使用することをお勧めします`Boolean()`同様に`Number()`そして`String()`関数は明示的に変換されます。

### ブール値に自動的に変換します

JavaScriptはブール値になると予想される場所に遭遇します（`if`ステートメントの条件付き部分）は、非ブール値のパラメーターをブール値に自動的に変換します。`Boolean()`関数。

したがって、次の5つの値を除き、他のすべてが自動的に変換されます`true`次に、

- `undefined`
- `null`
- `+0`または`-0`
- `NaN`
- `''`（空の文字列）

次の例では、条件部分の各値は`false`ネガティブオペレーターを使用した後、それはなります`true`次に、

```javascript
if ( !undefined
  && !null
  && !0
  && !NaN
  && !''
) {
  console.log('true');
} // true
```

次の2つの執筆方法は、式をブール値に変換するために使用されることがあります`Boolean()`関数。

```javascript
// 写法一
expression ? true : false

// 写法二
!! expression
```

### 文字列への自動変換

JavaScriptは、文字列になると予想される場合、非ストリングの値を文字列に自動的に回します。

文字列の自動変換は、主に文字列の追加操作と他の値が非Stringである場合、後者が文字列に変換されるときに発生します。

```javascript
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
```

この自動変換は間違いを犯すのが簡単です。

```javascript
var obj = {
  width: '100'
};

obj.width + 20 // "10020"
```

上記のコードでは、開発者は戻ることを期待するかもしれません`120`、しかし、自動変換のために、実際にはキャラクターが返されました`10020`次に、

### 値への自動変換

JavaScriptは、PARAMETER値を値に直面する値に自動的に変換します。`Number()`関数。

オペレーターの追加に加えて（`+`）輸送オペレーターを文字列に変換することが可能であり、他の演算子はオペレーターを自動的に価値に変換します。

```javascript
'5' - '2' // 3
'5' * '2' // 10
true - 1  // 0
false - 1 // -1
'1' - 1   // 0
'5' * []    // 0
false / '5' // 0
'abc' - 1   // NaN
null + 1 // 1
undefined + 1 // NaN
```

上記のコードでは、演算子の両側の演算子が値に変換されます。

> 知らせ：`null`数値に目を向けるとき`0`、そして`undefined`数値に目を向けるとき`NaN`次に、

One -Dollarコンピューティングシンボルは、演算子を値に変えます。

```javascript
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
```

## 参照リンク

- Axel Rauschmayer、[JavaScriptの{} + {}とは何ですか？](http://www.2ality.com/2012/01/object-plus-object.html)
- Axel Rauschmayer、[JavaScript Quirk 1：値の暗黙的な変換](http://www.2ality.com/2013/04/quirk-implicit-conversion.html)
- ベンジー・ギラム、[Quantum JavaScript？](http://www.benjiegillam.com/2013/06/quantum-javascript/)

# エラー処理メカニズム

## エラーインスタンスオブジェクト

JavaScriptの分析または実行すると、エラーが発生すると、エラーオブジェクトが提供されます`Error`関数を構築すると、すべてのスローエラーがこのコンストラクターのインスタンスです。

```javascript
var err = new Error('出错了');
err.message // "出错了"
```

上記のコードでは、呼び出します`Error()`関数を構築し、インスタンスオブジェクトを生成します`err`次に、`Error()`コンストラクターはパラメーターを受け入れ、エラープロンプトを示します。`message`属性でこのパラメーターを読んでください`Error`インスタンスオブジェクトの後、プログラム全体がエラーが発生し、実行されなくなった場所で中断されます。

JavaScript言語標準は言及されています、`Error`オブジェクトの例が必要です`message`属性は、エラーの迅速な情報を示し、他の属性が言及されていません`Error`例も提供します`name`そして`stack`属性、間違った名前の名前、エラーのスタックですが、それらはすべての実装ではなく、標準以外です。

- **メッセージ**：エラープロンプト情報
- **名前**：エラー名（非標準属性）
- **スタック**：間違ったスタック（標準以外の属性）

使用`name`そして`message`これらの2つの属性は、何が起こったのかを一般的に理解することができます。

```javascript
if (error.name) {
  console.log(error.name + ': ' + error.message);
}
```

`stack`属性は、エラーが発生したときにスタックを表示するために使用されます。

```javascript
function throwit() {
  throw new Error('');
}

function catchit() {
  try {
    throwit();
  } catch(e) {
    console.log(e.stack); // print stack trace
  }
}

catchit()
// Error
//    at throwit (~/examples/throwcatch.js:9:11)
//    at catchit (~/examples/throwcatch.js:3:9)
//    at repl:1:5
```

上記のコードでは、エラースタックの最も内側のレイヤーが`throwit`次に、機能します`catchit`関数、最後に関数の動作環境。

## 原始エラータイプ

`Error`インスタンスオブジェクトは、最も一般的なタイプです`Error`6つの派生オブジェクト。

### SyntaxErrorオブジェクト

`SyntaxError`オブジェクトは、コードが解析されているときに発生する構文エラーです。

```javascript
// 变量名错误
var 1a;
// Uncaught SyntaxError: Invalid or unexpected token

// 缺少括号
console.log 'hello');
// Uncaught SyntaxError: Unexpected string
```

上記のコードのエラーは文法分析段階にあるので、それを捨てます`SyntaxError`最初のエラープロンプトは「トークン違法」であり、2番目のエラープロンプトは「文字列が要件を満たしていない」です。

### 参照エラーオブジェクト

`ReferenceError`オブジェクトは、不人気な変数のときに発生する参照エラーです。

```javascript
// 使用一个不存在的变量
unknownVariable
// Uncaught ReferenceError: unknownVariable is not defined
```

別のトリガーシーンは、関数の実行結果を割り当てるなど、避けられないオブジェクトに1つの値を割り当てることです。

```javascript
// 等号左侧不是变量
console.log() = 1
// Uncaught ReferenceError: Invalid left-hand side in assignment
```

上記のコードは関数のペアです`console.log`操作結果が割り当てられ、結果がトリガーされます`ReferenceError`間違い。 

### RangeError オブジェクト

`RangeError`オブジェクトは、値が有効な範囲を超えたときに発生するエラーです。`Number`オブジェクトのメソッドパラメーターは範囲を超え、関数スタックは最大値を超えます。

```javascript
// 数组长度不得为负数
new Array(-1)
// Uncaught RangeError: Invalid array length
```

### Typerrorオブジェクト

`TypeError`オブジェクトは、たとえば、変数またはパラメーターが予想されるタイプではない場合に発生するエラーです。`new`コマンドはこの間違いを投げかけます`new`コマンドのパラメーターはコンストラクターである必要があります。

```javascript
new 123
// Uncaught TypeError: 123 is not a constructor

var obj = {};
obj.unknownMethod()
// Uncaught TypeError: obj.unknownMethod is not a function
```

上記のコードの2番目の状況、オブジェクトが存在しない方法は、それを捨てます`TypeError`エラー、からです`obj.unknownMethod`値はです`undefined`、関数ではありません。

### urierrorオブジェクト

`URIError`オブジェクトは、URI関連関数のパラメーターが正しくない場合にスローされるエラーであり、主に関与します`encodeURI()`同様に`decodeURI()`同様に`encodeURIComponent()`同様に`decodeURIComponent()`同様に`escape()`そして`unescape()`これらの6つの機能。

```javascript
decodeURI('%2')
// URIError: URI malformed
```

### EvalErrorオブジェクト

`eval`関数が正しく実行されない場合、それはそれを捨てます`EvalError`エラーのタイプは使用されなくなりました。

### 要約します

以上の6つの派生エラーとオリジナルエラー`Error`オブジェクトは、それらを使用して手動でエラーを生成することができます。

```javascript
var err1 = new Error('出错了！');
var err2 = new RangeError('出错了,变量超出有效范围！');
var err3 = new TypeError('出错了,变量类型无效！');

err1.message // "出错了！"
err2.message // "出错了,变量超出有效范围！"
err3.message // "出错了,变量类型无效！"
```

## カスタムエラー

JavaScriptがNATILYで提供する7つのエラーオブジェクトに加えて、エラーオブジェクトを定義することもできます。

```javascript
function UserError(message) {
  this.message = message || '默认信息';
  this.name = 'UserError';
}

UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
```

上記のコードはエラーオブジェクトをカスタマイズします`UserError`それを継承させてください`Error`オブジェクト。そのようなカスタムタイプエラーを生成できます。

```javascript
new UserError('这是自定义的错误！');
```

## ステートメントを投げます

`throw`ステートメントの役割は、手動中断プログラムの実行であり、エラーが発生します。

```javascript
var x = -1;

if (x <= 0) {
  throw new Error('x 必须为正数');
}
// Uncaught Error: x 必须为正数
```

上記のコードでは、変数の場合`x`等しくない`0`、間違いを手動で投げるだけで、ユーザーに伝えてください`x`値が正しくない場合、プログラム全体がここで中断されます。`throw`スローされたエラーはそのパラメーターです、これはここにあります`Error`オブジェクトの例。

`throw`カスタムエラーをスローすることもできます。

```javascript
function UserError(message) {
  this.message = message || '默认信息';
  this.name = 'UserError';
}

throw new UserError('出错了！');
// Uncaught UserError {message: "出错了！", name: "UserError"}
```

上記のコードでは、`throw`投げます`UserError`例。

実は、`throw`あなたはあらゆるタイプの価値を投げることができます。

```javascript
// 抛出一个字符串
throw 'Error！';
// Uncaught Error！

// 抛出一个数值
throw 42;
// Uncaught 42

// 抛出一个布尔值
throw true;
// Uncaught true

// 抛出一个对象
throw {
  toString: function () {
    return 'Error!';
  }
};
// Uncaught {toString: ƒ}
```

JavaScriptエンジンの場合、遭遇`throw`プログラムは停止します`throw`スローされた情報は、他のタイプのエラーの例または値です。

## 試してみてください...キャッチ構造

エラーが発生すると、プログラムが実行されます`try...catch`構造、エラーに対処することができ、実行するかどうかを選択します。

```javascript
try {
  throw new Error('出错了!');
} catch (e) {
  console.log(e.name + ": " + e.message);
  console.log(e.stack);
}
// Error: 出错了!
//   at <anonymous>:3:9
//   ...
```

上記のコードでは、`try`コードブロックはエラーのスローです（上記の例は`throw`エンターテイメント）、JavaScriptエンジンはすぐにコードを実行し、`catch`コードブロック、または間違っています`catch`コードブロックキャプチャ。`catch`パラメーターを受け入れ、示します`try`コードブロックの値。

いくつかのコードがエラーを報告するかどうかわからない場合は、それらを入れることができます`try...catch`コードブロックでは、エラーをさらに処理するのが便利です。

```javascript
try {
  f();
} catch(e) {
  // 处理错误
}
```

上記のコードでは、関数の場合`f`エラーを実行すると、実行されます`catch`コードブロック、次にエラーを処理します。

`catch`コードブロックがキャプチャされた後、プログラムは中断されず、通常のプロセスに従って実行され続けます。

```javascript
try {
  throw "出错了";
} catch (e) {
  console.log(111);
}
console.log(222);
// 111
// 222
```

上記のコードでは、`try`コードブロックによってスローされるエラーはです`catch`コードブロックがキャプチャされた後、プログラムは引き続き実行されます。

`catch`コードブロックでは、もう一度エラーを投げるか、ネストされたものを使用することもできます`try...catch`構造。

```javascript
var n = 100;

try {
  throw n;
} catch (e) {
  if (e <= 50) {
    // ...
  } else {
    throw e;
  }
}
// Uncaught 100
```

上記のコードでは、`catch`コードにエラーがスローされました。

さまざまなタイプのエラーをキャプチャするために、`catch`コードブロックに判断ステートメントを追加できます。

```javascript
try {
  foo.bar();
} catch (e) {
  if (e instanceof EvalError) {
    console.log(e.name + ": " + e.message);
  } else if (e instanceof RangeError) {
    console.log(e.name + ": " + e.message);
  }
  // ...
}
```

上記のコードでは、`catch`キャプチャエラーの後、エラーのタイプが判断されます（`EvalError`まだ`RangeError`）、異なる治療。

## 最後にコードのブロック

`try...catch`構造を使用すると、最後に1つ追加できます`finally`コードブロックは、エラーがあるかどうかに関係なく、最終操作で実行されなければならない文です。

```javascript
function cleansUp() {
  try {
    throw new Error('出错了……');
    console.log('此行不会执行');
  } finally {
    console.log('完成清理工作');
  }
}

cleansUp()
// 完成清理工作
// Uncaught Error: 出错了……
//    at cleansUp (<anonymous>:3:11)
//    at <anonymous>:10:1
```

上記のコードでは、NOがあるためです`catch`文ブロックでは、エラーが発生すると、中断が実行される前に、`finally`コードブロック、次にユーザーにエラーメッセージの報告を求めます。

```javascript
function idle(x) {
  try {
    console.log(x);
    return 'result';
  } finally {
    console.log('FINALLY');
  }
}

idle('hello')
// hello
// FINALLY
```

上記のコードでは、`try`コードブロックにエラーはありません。また`return`文、しかし`finally`さらに、コードブロックは実行されます。`result`次に、

次の例の説明、`return`ステートメントの実行はランク付けされています`finally`コードの前に、待ってください`finally`コードが実行された後、返されます。

```javascript
var count = 0;
function countUp() {
  try {
    return count;
  } finally {
    count++;
  }
}

countUp()
// 0
count
// 1
```

上記のコードが説明しています、`return`声明で`count`値はこちらです`finally`実行する前にコードブロックを取得します。

以下は次のとおりです`finally`コードブロック使用の典型的なシーン。

```javascript
openFile();

try {
  writeFile(Data);
} catch(e) {
  handleError(e);
} finally {
  closeFile();
}
```

上記のコードは最初にファイルを開き、次に`try`コードブロックにファイルを書き込みます。エラーがない場合は、実行します`finally`コードブロックはファイルを閉じます`catch`コードブロック処理エラーを使用して、使用します`finally`コードブロック閉じたファイル。

次の例は完全に反映されています`try...catch...finally`3つの間の実行順序。

```javascript
function f() {
  try {
    console.log(0);
    throw 'bug';
  } catch(e) {
    console.log(1);
    return true; // 这句原本会延迟到 finally 代码块结束再执行
    console.log(2); // 不会运行
  } finally {
    console.log(3);
    return false; // 这句会覆盖掉前面那句 return
    console.log(4); // 不会运行
  }

  console.log(5); // 不会运行
}

var result = f();
// 0
// 1
// 3

result
// false
```

上記のコードでは、`catch`コードブロックが実行される前に、それは実行されます`finally`コードブロック。

`catch`コードブロックでは、トリガーが`finally`コードブロックのロゴは利用可能であるだけではありません`return`文、そしてあります`throw`文。

```javascript
function f() {
  try {
    throw '出错了！';
  } catch(e) {
    console.log('捕捉到内部错误');
    throw e; // 这句原本会等到finally结束再执行
  } finally {
    return false; // 直接返回
  }
}

try {
  f();
} catch(e) {
  // 此处不会执行
  console.log('caught outer "bogus"');
}

//  捕捉到内部错误
```

上記のコードで、入力します`catch`コードブロックの後、私は出会いました`throw`ステートメント、実行します`finally`コードブロック、それ`return false`文章なので、私は直接戻ってきて、もはや実行に戻りません`catch`コードブロックの残りの部分。

`try`コードブロック内で、もう一度使用できます`try`コードブロック。

```javascript
try {
  try {
    consle.log('Hello world!'); // 报错
  }
  finally {
    console.log('Finally');
  }
  console.log('Will I run?');
} catch(error) {
  console.error(error.message);
}
// Finally
// consle is not defined
```

上記のコードでは、`try`中には1つあります`try`内層`try`エラー （`console`間違っています）、その後、内側の層が実行されます`finally`コードブロック、次にエラーをスローし、外側の層を取得します`catch`捕獲。

## 参照接続

- ジャニ・ハルティカイネン、[JavaScriptエラーとそれらを修正する方法](http://davidwalsh.name/fix-javascript-errors)

# コンソールオブジェクトとコンソール

## コンソールオブジェクト

`console`オブジェクトはJavaScriptのネイティブオブジェクトであり、UNIXシステムの標準出力に少し似ています`stdout`エラーエラー`stderr`さまざまな情報をコンソールに出力し、多くの便利な補助方法も提供できます。

`console`2つの一般的な用途があります。

- プログラムをデバッグして、Webコードが実行されているときにエラーメッセージを表示します。
- Webコードと対話するために、コマンドラインインターフェイスが提供されます。

`console`オブジェクトのブラウザの実装は、ブラウザに付属する開発ツールに含まれています。

1. F12を押します`Control + Shift + i`（PC）/`Command + Option + i`（マック）。
2. ブラウザメニュー「ツール/開発者ツール」を選択します。
3. ページ要素で、右側のメニューをクリックして、「要素を検査する」を選択します。

開発者ツールを開いた後、上部に複数のパネルがあります。

- **要素**：WebページでHTMLソースコードとCSSコードを表示します。
- **リソース**：ロードされたさまざまなリソースファイル（コードファイル、フォントファイルCSSファイルなど）、およびハードディスクで作成されたさまざまなコンテンツ（ローカルキャッシュ、Cookie、ローカルストレージなど）を表示します。
- **通信網**：WebページのHTTP通信状況を表示します。
- **ソース**：Webページで読み込まれたスクリプトソースコードを表示します。
- **タイムライン**：さまざまなウェブページの動作が時間とともに変化する状況を表示します。
- **パフォーマンス**：CPUやメモリ消費など、Webページのパフォーマンスを表示します。
- **コンソール**：JavaScriptコマンドを実行するために使用されます。

これらのパネルには独自の使用があります`Console`パネル（コンソールとも呼ばれます）。

`Console`パネルは基本的にコマンドラインウィンドウです。

## コンソールオブジェクトの静的方法

`console`オブジェクトによって提供されるさまざまな静的メソッドは、コンソールウィンドウと対話するために使用されます。

### console.log（）、console.info（）、console.debug（）

`console.log`コンソールの出力情報の方法。1つ以上のパラメーターを受け入れ、それらを出力に接続できます。

```javascript
console.log('Hello World')
// Hello World
console.log('a', 'b', 'c')
// a b c
```

`console.log`メソッドは、各出力の最後に行を自動的に追加します。

```javascript
console.log(1);
console.log(2);
console.log(3);
// 1
// 2
// 3
```

最初のパラメーターがフォーマット文字列の場合（フォーマット配置記号を使用）、`console.log`メソッドは後続のパラメーターに置き換えられ、出力が実行されます。

```javascript
console.log(' %s + %s = %s', 1, 1, 2)
//  1 + 1 = 2
```

上記のコードでは、`console.log`メソッドの最初のパラメーターには3つのプレースホルダーがいます（`%s`）、2番目、3番目、および4つのパラメーターは、表示時に3つのシート占有率を順番に置き換えます。

`console.log`次のプレースホルダーをサポートする方法。

- `%s` String
- `%d` 整数
- `%i` 整数
- `%f` フローティングポイント番号
- `%o` オブジェクトリンク
- `%c` CSS形式文字列

```javascript
var number = 11 * 9;
var color = 'red';

console.log('%d %s balloons', number, color);
// 99 red balloons
```

上記のコードでは、2番目のパラメーターは値であり、対応する場所は`%d`3番目のパラメーターは文字列であり、対応する場所は`%s`次に、

使用`%c`場所を占有する場合、対応するパラメーターは、出力コンテンツをレンダリングするためにCSSコードでなければなりません。

```javascript
console.log(
  '%cThis text is styled!',
  'color: red; background: yellow; font-size: 24px;'
)
```

上記のコードが実行された後、出力コンテンツは黄色のボトムレッドレターとして表示されます。

`console.log`メソッドの2つのパラメーター形式を一緒に使用できます。

```javascript
console.log(' %s + %s ', 1, 1, '= 2')
// 1 + 1  = 2
```

パラメーターがオブジェクトの場合、`console.log`オブジェクトの値が表示されます。

```javascript
console.log({foo: 'bar'})
// Object {foo: "bar"}
console.log(Date)
// function Date() { [native code] }
```

上記のコード出力`Date`オブジェクトの値、結果はコンストラクターです。

`console.info`はい`console.log`メソッドの方法はまったく同じ使用法です。`console.info`このメソッドは、出力情報の前に青いアイコンを追加します。

`console.debug`方法と`console.log`この方法は、デフォルトでは、出力デバッグ情報に似ています。`console.debug`出力情報は表示されず、表示レベルのみが開いています`verbose`ケースに表示されます。

`console`したがって、オブジェクトのすべての方法をカバーできます。`console.log`方法。 

```javascript
['log', 'info', 'warn', 'error'].forEach(function(method) {
  console[method] = console[method].bind(
    console,
    new Date().toISOString()
  );
});

console.log("出错了！");
// 2014-05-18T09:00.000Z 出错了！
```

上記のコードは、カスタマイズされたものを使用することを示しています`console.log`方法では、表示結果に現在の時間を追加できます。

### console.warn（）、console.error（）

`warn`方法と`error`この方法は、コンソールの出力情報でもあります。`log`方法の違いはそれです`warn`出力情報の場合、正面に黄色の三角形を追加し、警告を示します。`error`出力情報の場合、エラーを同時に示します。

```javascript
console.error('Error: %s (%i)', 'Server is not responding', 500)
// Error: Server is not responding (500)
console.warn('Warning! Too few nodes (%d)', document.childNodes.length)
// Warning! Too few nodes (1)
```

このように理解することができます、`log`この方法は、標準出力を書き込むことです（`stdout`）、、`warn`方法と`error`この方法は、標準誤差を書き込むことです（`stderr`））。

### console.table（）

一部の複合データの場合、`console.table`メソッドをテーブルディスプレイにすることができます。

```javascript
var languages = [
  { name: "JavaScript", fileExtension: ".js" },
  { name: "TypeScript", fileExtension: ".ts" },
  { name: "CoffeeScript", fileExtension: ".coffee" }
];

console.table(languages);
```

その上`language`変数は、次のように表に変わります。

（索引）|名前|fileextension
-------|----|-------------
0|"JavaScript"|".js"
1|"TypeScript"|".ts"
2|"CoffeeScript"|".coffee"

以下は、ディスプレイフォームのコンテンツの例です。

```javascript
var languages = {
  csharp: { name: "C#", paradigm: "object-oriented" },
  fsharp: { name: "F#", paradigm: "functional" }
};

console.table(languages);
```

その上`language`、次のようにテーブルに入ります。

（索引）|名前|パラダイム
-------|----|--------
Cシャープ|"C#"|"object-oriented"
fsharp|"F#"|"functional"

### console.count（）

`count`この方法は、カウントに使用され、出力の数倍に呼び出されます。

```javascript
function greet(user) {
  console.count();
  return 'hi ' + user;
}

greet('bob')
//  : 1
// "hi bob"

greet('alice')
//  : 2
// "hi alice"

greet('bob')
//  : 3
// "hi bob"
```

上記のコードは毎回呼び出されます`greet`関数、内部`console.count`この方法は、出力実行の数です。

この方法は、文字列をパラメーターとして受け入れ、実行数を分類するためのラベルを受け入れることができます。

```javascript
function greet(user) {
  console.count(user);
  return "hi " + user;
}

greet('bob')
// bob: 1
// "hi bob"

greet('alice')
// alice: 1
// "hi alice"

greet('bob')
// bob: 2
// "hi bob"
```

上記のコードは、パラメーターに応じて表示され、表示されます`bob`エグゼクティブ2回、`alice`かつてエグゼクティブ。

### console.dir（）、console.dirxml（）

`dir`読みやすく印刷しやすい形式でオブジェクトと表示を確認する方法。

```javascript
console.log({f1: 'foo', f2: 'bar'})
// Object {f1: "foo", f2: "bar"}

console.dir({f1: 'foo', f2: 'bar'})
// Object
//   f1: "foo"
//   f2: "bar"
//   __proto__: Object
```

上記のコード表示`dir`メソッドの出力結果の方が優れています`log`この方法は読みやすく、情報はより豊富です。

この方法は、DOMオブジェクトのすべての属性を表示するため、出力DOMオブジェクトにとって非常に役立ちます。

```javascript
console.dir(document.body)
```

ノード環境では、高いコードの形で出力を指定することもできます。

```javascript
console.dir(obj, {colors: true})
```

`dirxml`この方法は、主にDOMノードを表示するためにディレクトリツリーの形式で使用されます。

```javascript
console.dirxml(document.body)
```

パラメーターがDOMノードではなく、通常のJavaScriptオブジェクトである場合、`console.dirxml`に相当`console.dir`次に、

```javascript
console.dirxml([1, 2, 3])
// 等同于
console.dir([1, 2, 3])
```

### console.assert（）

`console.assert`メソッドは、条件が満たされていない場合、プログラムの操作のプロセスで使用されますが、これはプログラムの実行に相当します。

2つのパラメーターを受け入れます。最初のパラメーターは式です。2番目のパラメーターは文字列です`false`その後、コンソールに2番目のパラメーターが発生します。

```javascript
console.assert(false, '判断条件不成立')
// Assertion failed: 判断条件不成立

// 相当于
try {
  if (!false) {
    throw new Error('判断条件不成立');
  }
} catch(e) {
  console.error(e);
}
```

以下は、サブノードの数が500に相当するかどうかを判断します。

```javascript
console.assert(list.childNodes.length < 500, '节点个数大于等于500')
```

上記のコードでは、適格なノードが500未満の場合、出力は500以上の場合にのみ、コンソールのエラーを促し、指定されたテキストを表示します。

### console.time（）、console.timend（）

これらの2つの方法はタイミングに使用され、操作に費やされる正確な時間を計算できます。

```javascript
console.time('Array initialize');

var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
  array[i] = new Object();
};

console.timeEnd('Array initialize');
// Array initialize: 1914.481ms
```

`time`方法は時間の始まりを示します、`timeEnd`この方法は、タイミングの終わりを示しています`timeEnd`メソッドの後、コンソールは「タイマー名：The Time Consument」を表示します。

### console.group（）、console.groupend（）、console.groupCollapsed（）

`console.group`そして`console.groupEnd`これらの2つの方法は、表示された情報を出力する場合にのみ役立ちます。

```javascript
console.group('一级分组');
console.log('一级分组的内容');

console.group('二级分组');
console.log('二级分组的内容');

console.groupEnd(); // 二级分组结束
console.groupEnd(); // 一级分组结束
```

上記のコードには、「第1レベルのグループ化」内に「セカンドレベルのグループ」が表示され、「ファーストレベルグループ」と「セカンダリグループ」の前に折り畳みシンボルがあり、折り畳みに使用できます。クラスのコンテンツ。

`console.groupCollapsed`方法と`console.group`この方法は非常に似ています。

```javascript
console.groupCollapsed('Fetching Data');

console.log('Request Sent');
console.error('Error: Server not responding (500)');

console.groupEnd();
```

上記のコードは、「データの取得」のラインのみを示しています。

### console.trace（）、console.clear（）

`console.trace`メソッドスタック内の現在実行されているコードの呼び出しパスを表示します。

```javascript
console.trace()
// console.trace()
//   (anonymous function)
//   InjectedScript._evaluateOn
//   InjectedScript._evaluateAndWrap
//   InjectedScript.evaluate
```

`console.clear`現在のコンソールのすべての出力を削除し、ユーザーがコンソールの「保存ログ」オプションを選択した場合、カーソルを返します。`console.clear`メソッドは機能しません。

## コンソールコマンドラインAPI

使用に加えて、ブラウザコンソール`console`オブジェクト、コンソールに付属のコマンドラインメソッドを使用することもできます。

（1）`$_`

`$_`属性は、前の式の値を返します。

```javascript
2 + 2
// 4
$_
// 4
```

（2）`$0` - `$4`

コンソールは、要素パネル上の最後の5つで選択されたDOM要素を保存します。`$0`最初のカウントダウンを表します（最近のもの）、`$1`最後までのものを表し、まっすぐまで押すように`$4`次に、

（3）`$(selector)`

`$(selector)`最初の一致する要素に戻ることは同等です`document.querySelector()`ページスクリプトが正しい場合は注意してください`$`定義がある場合、元の定義をカバーします。ページには、コンソールの実行があります。`$(selector)`jQueryの実装は、配列を返すために使用されます。

（4）`$$(selector)`

`$$(selector)`選択したDOMオブジェクトに戻ります`document.querySelectorAll`次に、

（5）`$x(path)`

`$x(path)`方法特定のXPath式に一致するすべてのDOM要素を含む配列を返します。

```javascript
$x("//p[a]")
```

上記のコードはすべて含まれています`a`要素`p`要素。

（6）`inspect(object)`

`inspect(object)`メソッド関連パネルを開き、対応する要素を選択してDOM要素を表示します`Elements`たとえば、パネルに表示します`inspect(document)`要素パネルに表示されます`document`コントロールテーブルパネルの要素`Profiles`たとえば、パネルに表示します`inspect(window)`次に、

（7）`getEventListeners(object)`

`getEventListeners(object)`メソッドオブジェクトを返し、オブジェクトのメンバーは`object`コールバック関数のさまざまなイベント（など`click`または`keydown`）、各イベントはグループに対応し、配列のメンバーはインシデントのコールバック関数です。

（8）`keys(object)`、、、、`values(object)`

`keys(object)`メソッドを含む配列を返します`object`すべてのキー名。

`values(object)`メソッドを含む配列を返します`object`すべての重要な値。

```javascript
var o = {'p1': 'a', 'p2': 'b'};

keys(o)
// ["p1", "p2"]
values(o)
// ["a", "b"]
```

（9）`monitorEvents(object[, events]) ,unmonitorEvents(object[, events])`

`monitorEvents(object[, events])`メソッドは、特定のオブジェクトの特定のイベントを指定します`Event`インシデントの関連情報を含むオブジェクト。`unmonitorEvents`監視を停止する方法。

```javascript
monitorEvents(window, "resize");
monitorEvents(window, ["resize", "scroll"])
```

上記のコードは、単一のイベントと複数のイベントの監視方法を表します。

```javascript
monitorEvents($0, 'mouse');
unmonitorEvents($0, 'mousemove');
```

上記のコードは、監視を停止する方法を示しています。

`monitorEvents`同じ主要なカテゴリのイベントを聴くことができます。

- ねずみ："mousedown"、、、、"mouseup"、、、、"click"、、、、"dblclick"、、、、"mousemove"、、、、"mouseover"、、、、"mouseout"、、、、"mousewheel"
- 鍵："keydown"、、、、"keyup"、、、、"keypress"、、、、"textInput"
- 触る："touchstart"、、、、"touchmove"、、、、"touchend"、、、、"touchcancel"
- コントロール："resize"、、、、"scroll"、、、、"zoom"、、、、"focus"、、、、"blur"、、、、"select"、、、、"change"、、、、"submit"、、、、"reset"

```javascript
monitorEvents($("#msg"), "key");
```

上記のコードは、すべてを監視することを示しています`key`イベントのカテゴリ。

（10）その他の方法

コマンドラインAPIは、次の方法も提供します。

- `clear()`：コンソールの履歴をクリアします。
- `copy(object)`：特定のDOM要素をクリップボードにコピーします。
- `dir(object)`：特定のオブジェクトのすべての属性を表示します、はい、はい`console.dir`メソッドのエイリアス。
- `dirxml(object)`：特定のオブジェクトのXML形式を表示します、はい`console.dirxml`メソッドのエイリアス。

## デバッガーステートメント

`debugger`ステートメントは主にエラーを削除するために使用され、関数はブレークポイントを設定することです。`debugger`ステートメントが間違っている場合、自動的に停止します。`debugger`ステートメントは結果を生成しません。JavaScriptエンジンはこの文を自動的にスキップします。

Chromeブラウザでは、コードが実行されたとき`debugger`ステートメントの場合、操作は一時停止され、スクリプトソースコードインターフェイスが自動的に開かれます。

```javascript
for(var i = 0; i < 5; i++){
  console.log(i);
  if (i === 2) debugger;
}
```

上記のコードが0,1,2に印刷された後、一時停止され、ソースコードインターフェイスを自動的に開き、さらに処理を待ちます。

## 参照リンク

- Chrome開発者ツール、[コンソールを使用します](https://developers.google.com/chrome-developer-tools/docs/console)
- マットウェスト、[開発者ツールコンソールのマスタリング](http://blog.teamtreehouse.com/mastering-developer-tools-console)
- Firebug wiki、[コンソールAPI](https://getfirebug.com/wiki/index.php/Console_API)
- Axel Rauschmayer、[JavaScriptコンソールAPI](http://www.2ality.com/2013/10/console-api.html)
- マリウス・シュルツ、[Console.table（）を使用した高度なJavaScriptデバッグ](http://blog.mariusschulz.com/2013/11/13/advanced-javascript-debugging-with-consoletable)
- Google開発者、[コマンドラインAPIリファレンス](https://developers.google.com/chrome-developer-tools/docs/commandline-api)