#従来のコンパイル言語フロー(コンパイル)
1.分詞・品詞分析(形成品詞ユニット流)
2.解析/文法分析
このプロセスは、語法ユニットストリームを要素レベルごとにネストされた構成に変換するプログラムシンタックス解構成を表すツリーです。この木は「抽象文法樹」と呼ばれています。(Abstract Syntx Tree AST)
3.コード生成
JIT Just in time
AOT Ahead of time
#LHSとRHS
LHSは関連容器を見つける。
RHSは対応する値を見つける。
RHSクエリがネストされているすべてのスコープの中で必要な変数が見つからない場合、エンジンはReferenceErrerをスローします。
対照的に、エンジンがLHSクエリを実行すると、最上階(グローバルスコープ)でも目標変数が見つからない場合、グローバルスコープではその名前を持つ変数が作成され、エンジンに返却され、プログラムが非厳格モードで実行されることが前提となる。
ReferenceErrorは作用域判別失敗に関連していますが、Type Errorは作用域判別に成功しました。しかし、結果に対する操作は不法か不合理です。
#JS変数の割り当て操作
変数の割り当て操作は2つの動作を行います。まず、コンパイラは現在のスコープで変数を宣言します。(もし前に宣言されていないなら)、実行時にエンジンがスコープ内で変数を検索します。見つけられたら割り当てを行います。そうでなければエラーを報告します。
#語法の段階
関数がどこで呼び出されても、どのように呼び出されても、その語法のスコープは関数によって宣言された時の位置によってのみ決定されます。
ワードスコープ検索は一級の識別子だけを検索します。コードにfoo.bar.bazワードスコープを参照すればfoo識別子を検索するだけです。
#関数宣言関数式
関数宣言と関数表現を区別する最も簡単な方法は、functionキーのビットが声明の中に現れる位置を見ることである。Functionが宣言の最初の単語であるならば、関数宣言であり、そうでなければ関数表現です。
(function foo(){.})は関数式としてfooは.で表される位置にしかアクセスできないことを意味します。外部作用領域はだめです。
#位を進める
エンジンはJavaScriptコードを説明する前にまずコンパイルします。コンパイル段階の一部の作業は、すべての声明を見つけ、適切なスコープでそれらを関連付けることです。
a = 2
var a
console.log(a); // 2
console.log(a); //undefined
var a = 2;
コンパイラは次のように行います。
var a;
a=2
consolie.log(a)
var a;
consolie.log(a)
a=2
第一部分はコンパイルであり、第二部分は実行である。
foo()
function foo(){
consolone.log(a)//undefined
var a=2
)
各作用域は向上しますので、このコードは以下の形式として理解されます。
function foo(){
var a;
consolone.log(a)
a=2;
)
foo()
関数宣言は昇格関数式にはなりません。
foo()//ReferenceErrではなくTypeErr
var foo=function bar(){}
#スコープ
実際には、クローズドは普通にはっきりと切った事実です。つまり、私たちはワードのスコープの環境でコードを書きます。その中の関数も値です。自由に伝えられます。関数が覚えていて、既存の語法作用領域にアクセスできると、関数が現在の語法のスコープ外で実行されても、この関数は閉じられています。
function foo(){
var a = 2;
function bar(){
console.log(a)
}
return bar
}
var baz = foo();
baz() //2 これは閉包です
foo()が実行された後、エンジンにゴミ回収器がありますので、使用しないメモリを放出します。foo()の内容は使えないように見えますが、クローズドはこのようなことを防ぐことができます。bar()自体が使っているからです。
この関数は定義時の語法のスコープ以外で呼び出されます。クローズドは、関数が定義された時の動作領域にアクセスできるようにします。
内部関数を所在の品詞作用領域に渡す以外は、元の定義された作用領域に対する参照を持っています。この関数はどこで実行されてもクローズドされます。