写真のECMA-262(JavaScript)標準、パート1



JavaScriptデバイスについて多くの記事が書かれています。 まず、 「JavaScript。The kernel」です。 ドミトリーソシュニコフリチャードコーンフォードによる記事の翻訳、およびドミトリーフランクによる投稿 。 しかし、技術を十分に把握するには、主要な情報源に目を向けることをお勧めします。 この場合、 ECMA-262標準ECMAScript言語仕様に準拠します。 この投稿は、標準の調査を開始するための簡単な方法だと思います。 リンクをたどり、仕様書を読み、独自の図を作成することをお勧めします。

JavaScriptクロージャーの仕組み


主なECMAScript構造は、 実行コンテキスト語彙環境 、および環境レコードです。 それらは次のように接続されます。



VariableEnvironmentに加えて、 実行コンテキストにはLexicalEnvironmentもあります。違いの詳細については、 ECMAScript 5の仕様(LexicalEnvironmentとVariableEnvironment)を参照してください
ThisBindingについては、記事の次のパートで説明します。

環境レコードには、変数の値が格納されます。 var a = 1を宣言すると、現在のレコードに {a:1}が表示されます。 字句環境ではレコードのほかに、 外部フィールドもあります。 外部は、たとえば、ネストされた関数の場合の外部レキシカル環境を指します。

変数の検索は、現在のコンテキストのVariableEnvironmentで始まります。 この名前の変数がレコード内に見つからない場合外部環境でチェーンによって検索されます

プログラムが起動すると、グローバルコンテキスト環境が作成されます。 レコードとして、 グローバルオブジェクトが使用されます。



インタープリターがfunctionキーワードを検出するとFunctionObjectを作成します。 現在のレキシカル環境への参照は、作成されたFunctionObjectの scopeプロパティに書き込まれます。

表記function f(){} 、表記var f = function(){} function f(){}ほぼ同等です。ただし、最初の場合は、 function f()を含むブロックに入るとFunctionObjectが作成され、2番目は特定の行を実行するときに作成されます。



関数が呼び出されるたびに、新しいコンテキスト環境 、およびレコードが作成されます。 コンテキストはスタックにプッシュされ、関数を終了すると破棄されます。 作成された環境の 外側に 呼び出されたFunctionObjectの スコープ 書き込まれます。 関数がグローバルコンテキストで宣言された場合、 outerグローバル環境を指します



ここで、ある関数が別の関数を返すときの閉包を検討します。

 var x = 1; function f() { var x = 2; function g() { return x; } return g; } f()(); 

関数fが呼び出されると、 function g FunctionObjectと同様に、 fの コンテキスト環境 が作成されます。 スコープは、 VariableEnvironmentから現在の環境への参照を書き込みます。 fを終了すると、コンテキストは破棄されますが、返されるFunctionObjectからのリンクがあるため、 環境は残ります。



fから返された関数g 呼び出されると、 gのコンテキストと環境 が作成されます。 新しい環境外側は、呼び出されたFunctionObjectからスコープを書き込みます。 変数xの検索は、現在のVariableEnvironmentで始まり、次にouterまで続きます。 その結果、値x = 2が返されます。



記事の次の部分では 、ECMAScriptの観点からこれがどのように機能するかを調べます。

Source: https://habr.com/ru/post/J279421/


All Articles