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イメージの階層化の原理の詳細な説明

推薦する

10 HTML テーブル関連タグ

実際、多くの人が「テーブルは絶対に使用すべきではないと聞いたことがある」と言いますが、これは絶対に間...

Linux mysql-5.6 でルート パスワードをリセットする方法

1. MySQL サービスが起動しているかどうかを確認します。起動している場合は、MySQL サービ...

Linuxシステムの入出力管理とvimの共通機能の詳細な説明

####システム内の入出力の管理#### 1. システムの入力と出力のリダイレクトを理解する入力リダ...

ElementUI の this.$notify.close() 呼び出しが機能しない問題の解決方法

目次要件の説明問題の説明問題分析問題解決質問の拡張要件の説明このプロジェクトでは、まずユーザーが質問...

WindowsにMySQL5.7圧縮パッケージを素早くインストールする

この記事では、Windows に MySQL 5.7 圧縮パッケージをインストールする方法について説...

Linux manコマンドの具体的な使い方

01. コマンドの概要Linux には充実したヘルプ マニュアルが用意されています。コマンドのパラメ...

Ant Design Blazor コンポーネントライブラリのルーティング再利用マルチタブ機能

最近、Ant Design Blazor コンポーネント ライブラリにマルチタブ コンポーネントを実...

Docker Swarm クラスタ管理の使用と原理の分析

Swarm クラスター管理導入Docker Swarm は Docker 用のクラスター管理ツールで...

CSS -webkit-box-orient: コンパイル後に垂直プロパティが失われる

1. 原因要件は 2 行を表示することであり、余分なテキストは 3 つのドットに置き換えられるため、...

HTML 5 スタイルシートのリセット

この CSS リセットは、Eric Meyers の CSS リセットに基づいて変更されており、特に...

MySQL killコマンドの実行原理の詳細な説明

目次キル命令実行原理命令実行特性クエリ実行の強制終了の原則接続終了の実装原則中断される可能性はありま...

Mysql はテーブル内の古いデータを定期的にクリアし、いくつかのデータを保持します (推奨)

以下の目標を達成するため: Mysql データベースは、一定の間隔 (2 時間または 1 日、カスタ...

JavaScript で配列遅延評価ライブラリを実装する方法

目次概要達成方法具体的な実装評価関数の終了を決定する生成関数の範囲変換関数マップフィルター割り込み機...

要素複数フォーム検証の実装

プロジェクトでは、フォーム テストが頻繁に発生します。単一のフォーム テストについては、詳細な紹介が...

MySQL パフォーマンス チューニングについて知っておくべき 15 個の重要な変数 (要約)

序文: MYSQL は最も人気のある WEB バックエンド データベースです。最近、NOSQL がま...