ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript のスコープと代入操作の解析

JavaScript のスコープと代入操作の解析

怪我咯
怪我咯オリジナル
2017-04-05 14:59:45945ブラウズ

スコープは、さまざまなプログラミング言語の最も基本的な関数として存在し、プログラミングをより柔軟で興味深いものにします。その基本的な機能は、値を 変数 に保存し、その値にアクセスして変更できるようにすることです。

おそらく、私たちは皆、スコープのいくつかの概念とその拡張、クロージャーなどを知っていますが、これらの可能性と比較して、これらの変数がどこに格納され、プログラムがそれらにどのようにアクセスするかを理解する必要があります。もっと面白い。

var a = 1;

まず第一に、変数を宣言して値を割り当てるときに、プロセス全体に誰が関与しているのかを理解する必要があります。

1. エンジン: JS プログラム全体のコンパイルと実行に参加します。

2. コンパイラー: 構文分析とコード生成を担当します。

3. 範囲: 携帯電話と、一連の クエリ (変数) であるすべての識別子を管理し、現在実行されているコードがこれらの識別子へのアクセスに与える影響を判断するための非常に厳密なルールのセットを実装します。権利。

エンジンが var a =1; を見たとき、それは私たちが考えるものとは異なります。実際には 2 つの完全に異なるステートメントが存在します。1 つはコンパイラーによってコンパイルされたものです。 1 つは実行時に処理され、もう 1 つは実行時にエンジンによって処理されます。それでは、それらがどのように機能するかを見てみましょう。

コンパイラーは最初に var a = 1; このプログラムは字句単位に分解され、次に字句単位がツリー構造に解析されますが、コンパイラーがコードの生成を開始すると、このプログラムがどのように処理されるかが決まります。違いがあります。

私たちの理解の範囲では、コンパイラは次のように動作します。変数にメモリを割り当て、それに a という名前を付け、値 1 をこの変数に保存しますが、実際は異なります。

1. var a に遭遇すると、コンパイラーはまず、同じスコープのコレクション内にこの名前の変数がすでに存在するかどうかをスコープに尋ねます。そうである場合、コンパイラは宣言を無視してコンパイルを続行します。そうでない場合は、現在のスコープのコレクションで a という名前の変数を宣言するようにスコープに要求します。

2 を実行すると、コンパイラはエンジンの実行に必要なコードの生成を開始します。これらのコードは、a = 1 の代入演算を処理するために使用されます。次に、エンジンが実行されると、まず現在のスコープ セットに a という変数があるかどうかをスコープに問い合わせます。存在する場合、エンジンはこの変数を使用し、上位の変数を検索し続けます。 -level 現在のスコープ変数のスコープ。最後に、 a が見つかる限り、エンジンはそれに 1 を割り当てます。見つからない場合、エンジンは例外をスローします。

つまり、新しい変数の割り当てには 2 つの操作があります。1 つ目はコンパイラーが変数を宣言する操作で、2 つ目はエンジンがスコープ内で変数を見つけて値を割り当てる操作です。

以下の簡単なコードを見てください

function demo(a){
        console.log(a)          
}
demo(2);

続ける前に、LHS と RHS を見てみましょう。名前が示すように、一方は左で、もう一方は右です。これらは、変数に対してエンジンによって使用される 2 つのクエリであり、L と R は代入の左側と右側を表します。つまり、LHS クエリは、変数が代入の左側に出現するときに実行されます。右側の場合は RHS クエリ。しかし、より正確な表現は、RHS クエリは単に変数の値を検索するのに対し、LHS クエリは変数のコンテナ自体を検索してそれに値を割り当てるということです。したがって、このステートメントによれば、RHS が実際には「非左側」を表すことがわかります。簡単なコードを見てみましょう。

var a = 1; console.log(a);

在上面的代码中,var a =1;对a的引用是一个LHS引用,而console.log(a)的a其实就是一个RHS引用。再看一个例子:

function demo(a){
        console.log(a);   
}
demo(1);

上面的代码中其实包含了RHS和LHS引用。我们理解下demo(1);的意思,它其实意味着RHS引用demo这个值,(...)意味着它需要被执行,而在执行的过程中,有一个隐式的LRS引用 a = 1; 这个查询发生在参数传递的过程中。其中的console.log(a)也是个RHS引用。

同时我们需要知道,不成功的RHS会导致抛出一个异常,而不成功的LHS引用会导致自动隐式的创建一个全局变量(非严格模式),或者抛出异常(严格模式)。

作用域的嵌套

当一个块或者函数嵌套在另一个块或者函数内时,就发生了作用域的嵌套。因此,当在当前作用域中无法找到该变量时,引擎就会在外层嵌套的作用域中继续查找(若一直没有找到会到达全局作用域),直到找到该变量。

JavaScript のスコープと代入操作の解析

上图一层一层往外形成的结构就是我们常说的作用域链,最内层代表当前执行环境的作用域,最外层代表全局作用域。LHS和RHS都会在当前作用域进行查找,如果没有找到,就会向外,以此类推,如果到达全局作用域都没有找到,那无论如何这个查找过程都会停止。


以上がJavaScript のスコープと代入操作の解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。