JavaScript解析メカニズム——変数の理解を深める
3032 ワード
1.事前解析概念
現在の役割領域では、jsが実行される前に、varとfunctionのキーワードを持っている事前に声明を出してメモリに配置します.(このプロセスは変数アップとしても理解できます.)上から下までjs文を実行します.前解析はvarによって定義された変数とfunctionだけで発生します.
2.var宣言の変数
var宣言を使用した変数の事前解析:この名前が存在することを解析器に教え、デフォルトではこの変数の割り当て値はundefinedで、以下の通りです.
なお、変数宣言がvarを使用していない場合は、変数の昇格は存在しません.以下のとおりです
3.functin声明の関数
Function宣言関数を使用した事前解析:まず、解析器という関数名の存在を教えてください.そして、解析器という関数名の関数体は何かを教えています.以下のとおりです
4.変数または関数の上書き
同じスコープで同じ変数または関数を宣言すると、次のいずれかが前のいずれかをカバーします.以下のとおりです
なお、変数mが定義されていないと、関数は上書きされません.
現在の役割領域では、jsが実行される前に、varとfunctionのキーワードを持っている事前に声明を出してメモリに配置します.(このプロセスは変数アップとしても理解できます.)上から下までjs文を実行します.前解析はvarによって定義された変数とfunctionだけで発生します.
2.var宣言の変数
var宣言を使用した変数の事前解析:この名前が存在することを解析器に教え、デフォルトではこの変数の割り当て値はundefinedで、以下の通りです.
console.log(x); //undefined
var x = 5;
変数xはconsolone.logの後に定義されていますが、varで説明されているxはメモリに保存され、undefinedに値を与えてから上からjs文を実行します.その実行順序は以下の構成に似ています.var x;
console.log(x); //undefined
x = 5;
先にxを宣言しましたが、xはundefinedと定義されていません.出力の結果は自然にundefinedです.それからxに5を割り当てます.なお、変数宣言がvarを使用していない場合は、変数の昇格は存在しません.以下のとおりです
console.log(x); //error: x is not defined
x = 5;
xはvar声明を使用していないので、エラーを報告してもxが見つかりません.3.functin声明の関数
Function宣言関数を使用した事前解析:まず、解析器という関数名の存在を教えてください.そして、解析器という関数名の関数体は何かを教えています.以下のとおりです
console.log(f);
function f() {
console.log("xx");
}
宣言関数は関数全体を一番前に上げますので、ブラウザで結果は関数全体を出力します.結果は以下の通りです.function f() {
console.log("xx");
}
関数のスコープで変数を宣言すると、関数のスコープの一番上にも下記のようになります.var x = 5;
function f() {
console.log(x); //undefined
var x = 2;
}
f();
以上の大域作用域は変数xを宣言しましたが、関数の中にも変数xが宣言されていますので、先に関数の中に変数xがあるかどうかを調べます.あれば、大域的に検索することはできません.関数内の変数xは関数のスコープの先頭に引き上げられ、値はundefinedであるため、出力結果はundefinedとなり、以下のような構造になります.var x = 5;
function f() {
var x;
console.log(x); //undefined
x = 2;
}
f();
関数のパラメータは、関数のスコープの変数としても理解できます.var x = 5;
function f(x) {
console.log(x); //undefined
}
f();
console.log(x); //5
関数fに1つのモダリティxを渡すと、関数は呼び出し時に実パラメータを渡さないため、undefinedとなります.大域で出力xは自然に大域で変数xを検索します.結果は5です.4.変数または関数の上書き
同じスコープで同じ変数または関数を宣言すると、次のいずれかが前のいずれかをカバーします.以下のとおりです
var x = 5;
var x = 10;
console.log(x); //10
function f() {
console.log("xx");
}
function f() {
console.log("yy");
}
f(); //yy
宣言の関数が変数の名前と同じなら、どう上書きしますか?次の例が見られます.var f = 5;
function f() {
console.log("xx");
}
f(); //error: f is not a function
JavaScriptでは、関数の前解析優先度は変数の前解析より高いです.関数がどの位置にあるかにかかわらず、関数全体を一番前に上げるのが望ましい.したがって、上記の例では、関数fは変数fの下で定義されていますが、事前解析の際に関数fを解析してから変数fを解析し、後の変数fは前の関数fを上書きし、最後のfは5を数値タイプとしていますので、fタイムズを呼び出すのは間違いです.fは一つの函数ではありません.なお、変数mが定義されていないと、関数は上書きされません.
var f;
function f() {
console.log("xx");
}
f(); //xx
以上の知識を身につけて、次の例を見ます.console.log(x); //function x() {console.log(5);}
var x = 2;
console.log(x); //2
function x() {
console.log(3);
}
console.log(x); //2
var x = 3;
console.log(x); //3
function x() {
console.log(5);
}
console.log(x); //3
x(); error: x is not a function
以上の例では、2つの関数xが優先的に向上しているので、第2の関数xは第1の関数xをカバーしている.その後、2つの変数xが上昇し、変数xが上昇してundefinedとなるため、第2の関数はカバーされておらず、第1の出力xは第2の関数function x(){consone.logs(5);}となる.その後xは2に割り当てられ、第2の出力xは2になる.最初の関数xは前に引き上げられたので、3番目の出力xはまだ2です.その後xの値は3であるため、第4、第5の出力xの結果は3である.最後にxを呼び出します.xは数値タイプですので、エラーxは関数ではありません.