js の変数プロモーション メカニズムの詳細な紹介

王林
リリース: 2020-04-24 09:24:18
転載
2146 人が閲覧しました

js の変数プロモーション メカニズムの詳細な紹介

変数プロモーション

JavaScript における変数プロモーションには、var で宣言された変数と function で宣言された変数の 2 種類があります。

var で宣言された変数

まず次のコードを見てみましょう。

コード 1

console.log(a);

var a;
ログイン後にコピー

From によると、a の値は何ですか。従来のプログラミング言語の考え方では、コードは上から下に向かって実行されます。この考え方によれば、2行目に到達した時点では変数aが定義されていないため、エラーaはエラーとなります。 「未定義

」と報告されますが、実際には答えは未定義です

まあ、疑問はありますが、次のコードを見てみましょう

var a;
console.log(a);
ログイン後にコピー

2つの部分が一致していることがわかりました。のコードは同じなので、新しい質問があります。それは、var a があるかどうかは問題ではありません。その答えは常に未定義であり、変数が改善されるかのような錯覚を引き起こすため、コード 3 を書きました。

コード 3

console.log(a);
ログイン後にコピー

わかりました、ようやくエラーが報告されました。つまり、これは JavaScript コードが上から下まで実行されていないことを証明しています。少なくとも表面的には次のように見えます。

それでは、コード 4 を見てみましょう

コード 4

console.log(a);
var a = 2;
ログイン後にコピー

変数はプロモートされているため、答えは 2 ですが、実際にはまだ未定義です。なぜでしょうか。

現時点では、構文解析やコード生成などの汚れた作業を担当するコンパイラに依頼する必要があります。

コンパイラは var a = 2; を認識すると、それを 2 つの宣言、var a; と a = 2 として扱います。最初の宣言はコンパイル段階で行われ、2 番目の宣言は待機中になります。実行フェーズに適しています。

つまり、上記のコードは次のコードになります

var a;
console.log(a);
a = 2;
ログイン後にコピー

したがって、最終的には未定義になります

さて、冗長になりますが、このコードを見てください。 5

コード 5

a = 2;
var a;
console.log(a);
ログイン後にコピー

このコードの実際の実行順序とその答えは、誰もがすでに知っているはずです。はい、答えは 2 ですが、私が言いたいのは、変更することです。 2 行目はコメントアウトされていますが、答えは 2 のままですが、これは変数の昇格とは関係ありません。これは厳密モードと非厳密モードの問題です。非厳密モードでは、開発者はキーワードを使用してはなりません。変数を宣言しますが、厳密モードではこれは不可能です。エラーが報告されます。

関数で宣言された変数

var と同様、関数で宣言された変数もプロモートされます。

log(5);

function log(mes){
  console.log(mes)
}
ログイン後にコピー

変数プロモーションに関するこれまでの理解によれば、このコードの実際のシーケンスは次のとおりです。

function log(mes){
  console.log(mes)
}

log(5);
ログイン後にコピー

非常に良い、非常に正しいです。次のコードを見てください

log(5);

var log = function(mes){
  console.log(mes)
}
ログイン後にコピー

エラーが報告されました。ログは関数ではありません。ここから、この種の関数式は昇格されないことがわかります。関数宣言のみが昇格されます。先頭にコード console.log の行を追加してみてください。(log ) の場合、unknown が最初に出力されます。

したがって、ここでの実際の順序は次のとおりです

var log;
log(); //这时候只是声明了log这个变量,并不是函数,却用函数的方法调用它,所以会报错,说这不是一个函数。
log = function(mes){
  console.log(mes)
}
ログイン後にコピー

関数内で変数を宣言するには var を使用します

var で宣言された変数が昇格されることはわかっていますが、実際にはそうではありません。どの程度まで改善されるのか分かりません。

この前にコードを見てみましょう

var a = 4;

function foo(){
  var a = 5;
  console.log(a);

}
foo();

console.log(a)
ログイン後にコピー

答えは 5,4 で、最初に 5 を出力し、次に 4 を出力します。

var で宣言された変数には関数スコープがあるため、foo 内の a は外部の foo と関係がありません。この状況はまさに私が望んでいることです。

コードを再度変更してください

function foo(){
  a = 5
  console.log(a);
  var a;
}
foo();

console.log(a)
ログイン後にコピー

答えは 5、a は定義されていません

コードの 4 行目は 5 を出力し、9 行目はエラーを報告します。

この場合、変数の昇格は、変数が配置されているスコープの先頭にのみ昇格され、親スコープには昇格されません。

したがって、結論を導き出すことができます。変数のプロモーションは、変数をそのスコープの先頭にのみプロモートします。

関数の優先順位

var と function を使用するため、変数には昇格という機能があるので、同じ変数を両方で宣言するとどうなるでしょうか? タイトルを見れば関数が優先されることがわかります。

コードを詳しく見てください

foo();

var foo;

function foo(){
  console.log(1)
}

foo = function(){
  console.log(2)
}
ログイン後にコピー

答えは 1です

このコードは実際には次のようになります

function foo(){
  console.log(1)
}

foo();// 1

foo = function(){
  console.log(2)
}
ログイン後にコピー

よく見てください、var foo; が消えていますはい、エンジンによって無視され、重複した宣言とみなされて破棄されました。

わかりました。var で宣言された変数は関数宣言ほど優れていないため、関数宣言を使用して同じ変数を複数回宣言します。

foo()
function foo(){
  console.log(1);
}
foo()
function foo(){
  console.log(2);
}
foo()
function foo(){
  console.log(3);
}

foo()
ログイン後にコピー

foo は 3 回宣言され、4 回呼び出されます。各呼び出しの結果は 3 なので、最後の関数宣言は前の関数宣言を上書きします

しかし、var はまだ苦労したいのです。自分の存在意義を証明する必要があると今でも感じています。

foo()
function foo(){
  console.log(1);
}
var foo;
foo()
foo = function(){
  console.log(2);
}
foo()
function foo(){
  console.log(3);
}

foo()
ログイン後にコピー

注意して見てください。コードの中間部分が変更されており、3、3、2、2 を順番に出力しています。

var foo は無視されますが、次の関数は依然として役立ちます。コードは次のようになります。

function foo(){
  console.log(3);
}

foo();//3
foo();//3
foo = function(){
  console.log(2);
}
foo();//2
foo();//2
ログイン後にコピー

通常のブロック内で関数を宣言します

#以前はスコープ内で関数を宣言していましたが、ブロック内で関数を宣言します

function foo(){

  console.log(b); // undefined
  b(); //TypeError: b is not a function

  var a = true;

  if(a){
    function b(){
      console.log(2)
    }
    //下面这段代码和上面的结果一样
    // var b = function(){
 //      console.log(2)
 //    }
  }
  //b() --> 这里会被执行

}

foo()
ログイン後にコピー
上記のことから、b は未定義であるため、この変数はまだ存在しますが、関数ではないことがわかります。この状況は、関数式を使用する場合と似ています。

概要


1. プロモーションは関数宣言のプロモーションと変数宣言のプロモーションに分けられます

2. var を使用して変数を宣言し、function を使用して関数を宣言します

3. 変数の昇格により、変数がそのスコープの最上位に昇格されます。

4. 関数式には昇格メカニズムはありません。

5. 関数宣言と変数宣言の宣言同じ識別子を同時に使用するシンボルでは、関数宣言が優先されます

6. 複数の関数が同じ識別子を宣言する場合、最後の宣言が前の宣言を上書きします

推奨チュートリアル: js チュートリアル

以上がjs の変数プロモーション メカニズムの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:jb51.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート