写真の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の観点からこれがどのように機能するかを調べます。




All Articles