JavaScript における変数と関数の昇格の詳細な例

JavaScript における変数と関数の昇格の詳細な例

js 実行

  • 字句解析フェーズ: 形式パラメータ解析、変数宣言解析、関数宣言解析の 3 つの部分が含まれます。字句解析により、記述した js コードは実行可能なコードに変換されます。
  • 実行フェーズ

可変ホイスト

  • 宣言のみがホイストされ、初期化はホイストされない
  • 宣言は現在のスコープの先頭に移動されます。

🌰 1:

コンソール.log(数値)
変数番号
数 = 6

プリコンパイル後

変数番号
console.log(num) // 未定義
数 = 6

🌰 2:

数 = 6
コンソール.log(数値)
変数番号

プリコンパイル後

変数番号
数 = 6
console.log(数値) // 6

🌰 3:

関数バー() {
    もし(!foo) {
        var foo = 5
    }
    コンソールログ(foo) // 5
}
バー()

プリコンパイル後

関数バー() {
    var foo // if文内で宣言が巻き上げられる if (!foo) {
        フー = 5
    }
    コンソールログ(foo)
}
バー()

機能の促進

  • 関数の宣言と初期化はホイストされる
  • 関数式は巻き上げられない

🌰 1: 関数宣言はホイストできる

コンソール.log(square(5)) // 25
関数 square(n) {
    n * nを返す
}

プリコンパイル後

関数 square(n) {
    n * nを返す
}
コンソール.log(square(5))

🌰 2: 関数式は巻き上げられない

console.log(square) // 未定義
console.log(square(5)) // squareは関数ではない
var square = 関数(n) {
    n * nを返す
}

プリコンパイル後

var スクエア
コンソール.log(四角形)
コンソール.log(square(5))
正方形 = 関数() {
    n * nを返す
}

🌰 3:

関数バー() {
    関数foo() // 2
    var foo = 関数() {
        コンソール.log(1)
    }
    関数foo() // 1
    関数foo(){
        コンソール.log(2)
    }
    関数foo() // 1
}
バー()

プリコンパイル後:

関数バー() {
    var foo
    foo = 関数 foo() {
        コンソール.log(2)
    }
    関数foo() // 2
    foo = 関数() {
        コンソール.log(1)
    }
    関数foo() // 1
    関数foo() // 1
}

関数の巻き上げは変数の巻き上げに先行する

🌰 1:

console.log(foo) // 関数を出力します function foo() {
    コンソールログ('foo')
}
var foo = 1

🌰 2:

var foo = 'hello' // こんにちは
;(関数(foo) {
    コンソールログ(foo)
    var foo = foo || 'world'
    console.log(foo) //こんにちは
})(フー)
console.log(foo) // こんにちは

プリコンパイル後

var foo = 'hello'
;(関数(foo) {
    var foo
    foo = 'hello' // foo の値がパラメータとして渡される console.log(foo) // hello
    foo = foo || 'world' // foo の値は hello なので、値 world は割り当てられません
    console.log(foo) // こんにちは
})(フー)
console.log(foo) // hello、グローバルスコープで var foo = 'hello' と出力します

JS変数の昇格と関数の昇格の順序

最近、筆記試験で変数巻き上げと関数巻き上げの順序を調べる問題に遭遇しました。以前は、var で定義された変数が巻き上げられ、関数宣言も巻き上げられることだけは知っていましたが、その順序や詳細なプロセスを深く勉強していませんでした。情報を調べ、自分で検証した結果、彼らの順序について自分なりの理解が得られました。それでは、早速本題に入りましょう。

まず結論を述べます。関数の昇格は変数の昇格よりも優先度が高く、宣言時に同じ名前の変数によって上書きされることはありませんが、同じ名前の変数に値が割り当てられた後には上書きされます。

次のコードが表示されます。

     console.log(a) // ƒ a(){} 変数 a に値を割り当てる前に、関数 a が出力されます。
     var a = 1;
     関数a(){}
     console.log(a) // 1 変数aに代入された後、出力される値は変数aの値になります

まず、変数と関数の両方の宣言がホイストされますが、関数のホイストの優先順位は変数よりも高くなります。両方がホイストされた後、変数は割り当てなしで定義されるだけなので、出力は function a になります。詳細なプロセスは次のとおりです。

     function a(){} // 関数宣言の昇格 a->fa (){}
     var a; // 変数の昇格 console.log(a) // この時点では、変数 a は代入なしで宣言されているだけなので、関数 a は上書きされません --> 出力 function afa (){}
     a=1; //変数の代入 console.log(a) // このとき、変数aに代入されます --> 変数a 1の値を出力します

概要: 関数宣言と変数は両方ともホイストされるため、関数の名前が変数と同じである場合、変数に値が割り当てられる前に関数が印刷され、変数に値が割り当てられた後に変数の値が印刷されます。

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

     (); // 2
     var a = function(){ // 変数aに割り当てられた関数として扱う
        コンソール.log(1)
     }
     (); // 1
     関数a(){
        コンソール.log(2)
     }
     (); // 1

実際には、関数宣言のみがホイストされ、関数式はホイストされないことをお伝えしたいだけです。したがって、関数式の後のコードは、変数 a がホイストされた関数 a を上書きするように割り当てられるため、1 を出力します。詳細なプロセスは次のとおりです。

     function a(){ // 関数の昇格 console.log(2)
     }
     var a; // 変数の昇格 a(); // 2  
     a = function(){ // 変数aが割り当てられると、上の関数aが上書きされます
         コンソール.log(1)
     }
     (); // 1
     (); // 1

別のコードを見てみましょう:

     ();
     関数a(){
         コンソール.log(1)
     }
     関数a(){
         コンソール.log(2)
     }

印刷されるのは 2 です。理由は単純で、最初に宣言されたものが、後で宣言されたものによって上書きされるからです。

要約する

これで、JavaScript の変数巻き上げと関数巻き上げに関するこの記事は終了です。より関連性の高い js 変数巻き上げと関数巻き上げのコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScriptの変数スコープについて学ぼう
  • JavaScript の変数スコープの詳細な説明
  • JavaScript での変数宣言をご存知ですか?
  • JavaScript 上級プログラミング: 変数とスコープ
  • JavaScript でローカル変数をグローバル変数に変換する方法
  • JavaScript 変数と変換の詳細

<<:  MySQL SELECT実行順序の簡単な理解

>>:  Dockerイメージの階層化の原理の詳細な説明

推薦する

MySQL 8.0 をインストールした後、初めてログインするときにパスワードを変更する問題を解決する

MySQL 8.0.16で初回ログイン時のパスワードを変更する方法を紹介します。 MySQLデータベ...

Linux クラウド サーバーに JDK と Tomcat をインストールするための詳細な手順 (推奨)

JDKをダウンロードしてインストールするステップ 1: まず、公式 Web サイト http://...

Win10にnginxをインストールする方法

会社から、負荷を実装するためにnginxをベースにFordプロジェクトのWebServiceサーバー...

Web デザインにおける Less と More について語る (写真)

Less is More は多くのデザイナーのキャッチフレーズです。これは建築界の巨匠ルートヴィヒ...

Hyper-v仮想マシンを使用してCentos7をインストールする

目次導入準備するシステムイメージをダウンロードHyper-Vを有効にする新しい仮想ネットワークスイッ...

ウェブページの読み込み速度を上げる6つのヒント

第二に、キーワードのランキングは、Webページの表示速度にも関係しています(参照:キーワードランキン...

js でオブジェクトを作成するさまざまな方法とその長所と短所のまとめ

目次初期作成方法ファクトリーパターンコンストラクターパターンコンストラクタパターンの最適化プロトタイ...

キャンバスはスクラッチカード効果を描画します

この記事では、キャンバスでスクラッチカード効果を描画するための具体的なコードを参考までに共有します。...

LinuxベースのLVMシームレスディスク水平拡張の詳細な説明

環境名前財産CPU 5650 円メモリ4Gディスク20G+4TB この時点で、サーバーにはすでに次の...

MySQL データベース監視ソフトウェア lepus の使用上の問題と解決策

lepus3.7 を使用して MySQL データベースを監視中に、次の問題が発生しました。このブログ...

Dockerを使用してSpringBootプロジェクトをデプロイする方法

Docker テクノロジの開発により、マイクロサービスの実装にさらに便利な環境が提供されます。Doc...

オブジェクトのプロパティを反復処理する際の TypeScript の問題

目次1. 問題2. 解決策1. オブジェクトをanyとして宣言する2. オブジェクトのインターフェー...

CentOS 7.6 への MySQL 5.7 GA バージョンのインストール チュートリアル図

目次環境の準備環境の準備mariadbをアンインストールする rpm -qa | grep mari...

Bootstrap 3.0 学習ノートのページレイアウト

今回はレイアウトを中心に学習しますが、これは基本的なHTMLタグのほとんどにも存在するため、比較的簡...

MySQL で誕生日から年齢を計算する複数の方法

以前はMySQLをあまり使用していなかったため、MySQLの機能にあまり詳しくありませんでした。この...