付録

プロトタイプの継承

nullundefined を除き、各プリミティブ データ型には prototype: 作業用のメソッドを提供する、対応するオブジェクト ラッパー あります。プリミティブでメソッドまたはプロパティのルックアップが呼び出されると、 JavaScript は、バックグラウンドでプリミティブをラップして、 代わりにラッパー オブジェクトでプロパティのルックアップを実行します。

たとえば、文字列リテラルには独自のメソッドはありませんが、 .toUpperCase() メソッド(対応する String オブジェクトのおかげで) ラッパー:

"this is a string literal".toUpperCase();
> THIS IS A STRING LITERAL

これはプロトタイプ継承と呼ばれ、プロパティやメソッドを継承する 値に対応するコンストラクタから取得できます。

Number.prototype
> Number { 0 }
>  constructor: function Number()
>  toExponential: function toExponential()
>  toFixed: function toFixed()
>  toLocaleString: function toLocaleString()
>  toPrecision: function toPrecision()
>  toString: function toString()
>  valueOf: function valueOf()
>  <prototype>: Object { … }

単に定義するだけでなく、これらのコンストラクタを使用してプリミティブを作成できます。 判断できますたとえば、String コンストラクタを使用すると、 文字列リテラルではなく、文字列オブジェクト: 文字列が含まれているだけでなく、 ただし、コンストラクタの継承されたプロパティとメソッドはすべて含まれます。

const myString = new String( "I'm a string." );

myString;
> String { "I'm a string." }

typeof myString;
> "object"

myString.valueOf();
> "I'm a string."

ほとんどの場合、結果のオブジェクトは 定義します。たとえば、 new Number コンストラクタの結果は、すべてのメソッドを含むオブジェクトになります。 Number プロトタイプのプロトタイピングでは、次の値に対して算術演算子を使用できます。 これらのオブジェクトは数値リテラルの場合と同様に、次のように記述されます。

const numberOne = new Number(1);
const numberTwo = new Number(2);

numberOne;
> Number { 1 }

typeof numberOne;
> "object"

numberTwo;
> Number { 2 }

typeof numberTwo;
> "object"

numberOne + numberTwo;
> 3

JavaScript に組み込まれているため、これらのコンストラクタを使用する必要はほとんどありません。 原型的な継承は、実際的なメリットがないことを意味します。作成中 コンストラクタを使用するプリミティブを使用する場合も、予期しない結果が生じることがあります。これは、 結果はオブジェクトであり、単純なリテラルではありません。

let stringLiteral = "String literal."

typeof stringLiteral;
> "string"

let stringObject = new String( "String object." );

stringObject
> "object"

これにより、厳密な比較演算子の使用が複雑になる可能性があります。

const myStringLiteral = "My string";
const myStringObject = new String( "My string" );

myStringLiteral === "My string";
> true

myStringObject === "My string";
> false

セミコロンの自動挿入(ASI)

スクリプトの解析中に、JavaScript インタープリタは 自動セミコロン挿入(ASI)を使用して、省略された セミコロンで区切ります。JavaScript パーサーは、許可されていないトークンを検出すると、 そのトークンの前にセミコロンを追加して、潜在的な構文エラーを修正しようとします。 ただし、次の条件の 1 つ以上に該当する必要があります。

  • トークンは改行で前のトークンと区切られます。
  • トークンは } です。
  • 前のトークンは ) で、挿入されたセミコロンが末尾になります。 do...while ステートメントのセミコロンを使用します。

詳しくは、ASI ルールをご覧ください。

たとえば、次のステートメントの後にセミコロンを省略しても、 構文エラーがあります。

const myVariable = 2
myVariable + 3
> 5

ただし、ASI では、同じ行に複数のステートメントを記述することはできません。もし 同じ行に複数の文を記述する場合は、必ず セミコロン:

const myVariable = 2 myVariable + 3
> Uncaught SyntaxError: unexpected token: identifier

const myVariable = 2; myVariable + 3;
> 5

ASI はエラーを訂正するための試みであり、構築された構文の柔軟性ではない 使用できます。セミコロンは適切に使用せず、必要に応じて使用しましょう。 正しいコードを生成します

厳格モード

JavaScript の記述方法を管理する標準は、 初期の段階で考慮されたあらゆることを学びました。Google Cloud コンソールに JavaScript の想定された動作によって、古いウェブサイトでエラーが発生することがないようにする必要があります。

ES5 では、JavaScript セマンティクスに関する長年の問題に対処しています。 「厳格モード」を導入して既存の実装を破壊します。選択する方法を スクリプト全体または特定の言語に対する特定の言語ルールに できます。厳格モードを有効にするには、文字列リテラルを使用します。 スクリプトの 1 行目に "use strict"、その後にセミコロンを付けます。 関数:

"use strict";
function myFunction() {
  "use strict";
}

厳格モードは特定の「安全でない」攻撃を非推奨となった機能、アクション、 一般的な「サイレント」モードの代わりに、使用し、使用する行為は禁止されています。 将来リリースされる言語機能と競合する可能性があるということです。たとえば 変数のスコープに関する設計上の決定事項 デベロッパーが誤って「汚染」する可能性が高くなり、グローバル スコープを 変数の宣言は、含まれているコンテキストに関係なく var キーワード:

(function() {
  mySloppyGlobal = true;
}());

mySloppyGlobal;
> true

最新の JavaScript ランタイムでは、次のリスクが伴うため、この動作を修正できません。 故意または故意に頼るウェブサイトの破壊 代わりに、最新の JavaScript では、デベロッパーが厳格なルールを 厳格モードがデフォルトで有効になり、 次のような新しい言語機能を導入する必要があります。

(function() {
    "use strict";
    mySloppyGlobal = true;
}());
> Uncaught ReferenceError: assignment to undeclared variable mySloppyGlobal

"use strict" を 文字列リテラルテンプレート リテラルuse strict)は機能しません。また、変数名の前に "use strict" を コードをその実行可能なコードに置く必要がありますそれ以外の場合、インタープリタはこれを無視します。

(function() {
    "use strict";
    let myVariable = "String.";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String."
> Uncaught ReferenceError: assignment to undeclared variable sloppyGlobal

(function() {
    let myVariable = "String.";
    "use strict";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String." // Because there was code prior to "use strict", this variable still pollutes the global scope

参照、値

オブジェクトのプロパティを含む任意の変数、 関数パラメータ、および arrayset、または map。これにはプリミティブまたは 値または参照値

ある変数から別の変数にプリミティブ値を代入すると、JavaScript では その値のコピーを作成して変数に代入します。

オブジェクト(クラスのインスタンス、配列、関数)を 変数を使用し、そのオブジェクトの新しいコピーを作成する代わりに、変数に メモリ内のオブジェクトの格納位置への参照です。そのため 変数で参照されるオブジェクトによって、参照されるオブジェクトも変更されるだけでなく、 返すことができます。たとえば、新しい Pod を 変数をオブジェクト参照を含む変数に置き換えてから、 変数を使用してそのオブジェクトにプロパティを追加すると、プロパティとその値が追加されます。 次のように変更します。

const myObject = {};
const myObjectReference = myObject;

myObjectReference.myProperty = true;

myObject;
> Object { myProperty: true }

これは、オブジェクトを変更するだけでなく、 これは、オブジェクト間の厳密な等価性を実現するには、両方の変数が 同じオブジェクトを参照し、true と評価します。参照できないことを 異なるオブジェクトに対して異なる結果を返すことができます。

const myObject = {};
const myReferencedObject = myObject;
const myNewObject = {};

myObject === myNewObject;
> false

myObject === myReferencedObject;
> true

メモリ割り当て

JavaScript は自動メモリ管理を使用するため、メモリがメモリがなくても 割り当てまたは割り当て解除を明示的に行うことができます。しばらく インフラストラクチャの詳細をメモリ管理に対するアプローチは、 メモリの割り当て方法を理解することは、 コンテキストです。

2 つの「分野」インメモリ: 「スタック」「ヒープ」です。スタックには 静的データ(プリミティブ値、オブジェクトへの参照)です。これは、 このデータの保存に必要な一定量のスペースを 表示されます。ヒープには、動的に割り当てられるスペースを必要とするオブジェクトが保存される 実行時にサイズが変更される可能性があるためですメモリがプロセスによって解放される 「ガベージ コレクション」と呼びます。これにより、参照のないオブジェクトが できます。

メインスレッド

JavaScript は基本的にシングルスレッド言語であり、「同期」 つまり、1 つのタスクしか実行できない 一度に 1 つずつですこの順次実行コンテキストはメインスレッドと呼ばれます。

main スレッドは、HTML の解析や ページの一部のレンダリングと再レンダリング、CSS アニメーションの実行、 単純なテキスト(テキストのハイライト表示など)から、 複合的な操作(フォーム要素の操作など)です。ブラウザ・ベンダーが 実行するタスクを最適化する方法の 1 つですが、より複雑です。 スクリプトは依然としてメインスレッドのリソースを過度に使用し、 向上します

一部のタスクは Web Workerと呼ばれるバックグラウンドスレッドに 次のような制限があります。

  • ワーカー スレッドは、スタンドアロン JavaScript ファイルに対してのみ機能します。
  • ブラウザ ウィンドウと UI へのアクセスが大幅に制限されるか、まったくアクセスできなくなります。
  • メインスレッドと通信する方法は制限されています。

このような制限があるため、リソース使用量の多い集中的なタスクや、 メインスレッドを占有する可能性があります。

コールスタック

「実行コンテキスト」を管理するために使用されるデータ構造、つまり、 コールスタックと呼ばれるリストです(多くの場合、 「スタック」と呼ばれるものです。スクリプトの初回実行時に、JavaScript インタープリタは 「グローバル実行コンテキスト」を作成するコールスタックに push します。 ステートメントが 1 つずつ実行されて、 下に表示されます。関数の実行時にインタープリタで関数呼び出しが発生すると、 「関数の実行コンテキスト」が push されます。その通話の スタックの一番上になり、グローバル実行コンテキストを一時停止して、関数を実行します。 実行コンテキストを指定します。

関数が呼び出されるたびに、その呼び出しの関数実行コンテキストが スタックの一番上、現在の実行コンテキストのすぐ上に push されます。 コールスタックは「先入れ先出し」方式で動作つまり、最もパフォーマンスの高い スタック内で一番上にある最新の関数呼び出しが実行され、 解決するまでお待ちください。関数が完了すると、インタープリタはその関数を削除します その関数呼び出しを含む実行コンテキストが 再びスタック内の最上位のアイテムとなり、実行が再開されます。

これらの実行コンテキストは、実行に必要な値をキャプチャします。。 スコープ内で使用可能な変数と関数についても 関数が呼び出され、その親コンテキストに基づいて 関数のコンテキストの this キーワード。

イベントループとコールバック キュー

この順次実行により、コールバックを含む非同期タスクが たとえば、サーバーからのデータの取得、ユーザー操作への応答、 setTimeout または setInterval で設定されたタイマーを待っていると、ブロックするか、 そのタスクが完了するまでメインスレッドを待機状態にするか、 現在の実行コンテキスト、コールバック関数の実行コンテキストが スタックに追加されます。これに対処するために、JavaScript は非同期タスクを管理します。 イベントドリブンの同時実行モデルを使用して「イベントループ」とおよび 「コールバック キュー」(「メッセージ キュー」と呼ばれることもあります)。

メインスレッドで非同期タスクを実行すると、 関数の実行コンテキストは、コールバックの上位ではなく、 あります。イベントループは、 reactor は、 コールスタックとコールバック キューのステータスをポーリングします。同じリージョンに イベントループがコールスタックが空であると判断した場合、 タスクが一度に 1 つずつスタックに push されて、 実行されます。