JavaScript の静的スコープと動的スコープを例を使って説明します

JavaScript の静的スコープと動的スコープを例を使って説明します

序文

記事の冒頭で、いくつかの概念を学びましょう。

  • スコープ: 「You Don't Know JS」では、スコープとは、エンジンが現在のスコープとネストされたサブスコープ内の識別子名に基づいて変数を検索する方法を管理する一連のルールであると指摘しています。簡単に言えば、スコープは変数の検索方法を指定します。
  • 静的スコープ: レキシカル スコープとも呼ばれる関数のスコープは、関数が定義されたときに決定されます。簡単に言えば、コードを書くときに変数とブロック スコープを記述する場所によって決定されます。
  • 動的スコープ: 関数のスコープは、関数が呼び出されたときに決定されます。

静的スコープと動的スコープ

JavaScript は静的スコープを使用し、関数定義の場所によって関数のスコープが決まります。

静的スコープと動的スコープの違いを理解するために例を見てみましょう。

var val = 1;
関数テスト() {
    コンソールログ(val);
}
関数バー() {
    var val = 2;
    テスト();
}

バー();
// 消す? ? ?

上記のコードでは:

  • まずグローバル変数valを定義し、それに1という値を割り当てます。
  • 関数textを宣言します。関数は変数valの値を印刷します。
  • 関数barを宣言し、関数内でローカル変数valを定義し、それに値2を割り当て、関数内でtest()関数を実行します。
  • bar()関数を実行する

静的スコープ実行プロセス

テスト関数を実行するときは、まずテスト関数内に変数 val があるかどうかを確認します。ない場合は、関数が定義されている場所に沿って検索し、前のレイヤーのコード内を検索して、値が 1 であるグローバル変数 val を見つけます。

スコープの検索は、実行時に常に最も内側のスコープから開始され、最初に一致する識別子が見つかるまで外側に移動します。

関数が呼び出される場所や呼び出される方法に関係なく、そのスコープは関数が定義されている場所によってのみ決定されます。

動的スコープ実行プロセス

test関数が実行されると、まず関数内からval変数が検索されます。見つからない場合は、呼び出し関数のスコープ、つまりbar関数のスコープからval変数が検索されます。そのため、印刷結果は2になります。

エクササイズ

静的スコープを理解し、消化するための 3 つの演習を見てみましょう。スコープは関数が定義されている場所によって決まります。

練習1

変数a = 1
関数fn1(){
    関数fn3(){
        変数a = 4
        fn2()
    }
    変数a = 2
    fn3を返す
}
関数fn2(){
    コンソールログ(a)
}
var fn = fn1()
関数()

上記のコードでは:

  • まずグローバル変数aを定義し、それに1という値を割り当てます。
  • 関数fn1を宣言し、関数内で関数fn3を宣言し、ローカル変数aを定義し、値2を割り当て、値fn3関数を返します。
  • fn3関数はローカル変数aを定義し、それに4の値を割り当て、fn2()を実行します。
  • 関数fn2を宣言します。関数の機能は、aの値を印刷することです。
  • fnにはfn1()の戻り値が割り当てられます。
  • fn() を実行します (fn3 関数を実行するのと同等)

質問を行う前に、静的スコープの概念を理解する必要があります。この問題では、fn2 はグローバルに定義されています。変数 a が fn2 で見つからない場合、fn1 および fn3 とは関係なくグローバルに検索され、1 が出力されます。

練習2

変数a = 1
関数fn1(){
    関数fn2(){
        コンソールログ(a)
    }
    関数fn3(){
        変数a = 4
        fn2()
    }
    変数a = 2
    fn3を返す
}
var fn = fn1()
関数()

fn2 は関数 fn1 内で定義されているため、fn2 内に変数 a がない場合、関数 fn3 とは関係のない fn1 内で検索されます。fn1 内で見つからない場合は、最初に一致する識別子が見つかるまで、fn1 が定義されている前のレベル (グローバル) 内で検索されます。この問題では、fn1で変数aを見つけて2を出力します。

練習3

var a = 1;
関数fn1(){
    関数fn3(){
        関数fn2(){
            コンソールログ(a)
        }
        var a;
        fn2()
        = 4
    }
    変数a = 2
    fn3を返す
}
var fn = fn1()
関数()

この問題では、fn2 は関数 fn3 で定義されています。変数 a が fn2 で見つからない場合、まず fn3 を検索します。それでも見つからない場合は、fn1 を検索します。この問題では、変数 a は fn3 にありますが、fn2() の実行時に a に値が割り当てられていないため、undefined が出力されます。

要約する

JavaScript の静的スコープに関しては、関数定義の場所によって関数のスコープが決まるという 1 つの文だけを覚えておく必要があります。疑問に遭遇したときは、他のコードに惑わされないでください。

JavaScript の静的スコープと動的スコープに関するこの記事はこれで終わりです。より関連性の高い JS の静的スコープと動的スコープのコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript 上級プログラミング: 変数とスコープ
  • JavaScript スコープチェーンの基本原理のグラフィカルな説明
  • Javascript のスコープとクロージャの詳細
  • JS の難しさ 同期と非同期、スコープとクロージャ、プロトタイプとプロトタイプ チェーンの詳細な説明
  • Vue.js スロットにおけるスコープ付きスロットの使用法の詳細な説明
  • js 実行コンテキストとスコープの概要
  • JS のスコープの問題に関する考えと共有

<<:  Tomcat を使用して IntelliJ IDEA によってデプロイされたプロジェクトの場所はどこですか?

>>:  大きな MySQL テーブルに列を追加する方法

推薦する

CSS3のtext-fill-colorプロパティの詳細な説明

text-fill-color とは何を意味しますか?文字通りの意味から言えば、「テキストの塗りつぶ...

Vue プロジェクトで addRoutes を使用する際の問題の解決策

目次序文1. 404 ページ1. 原因2. 解決策2.白い画面を更新する1. 原因2. 解決策3. ...

Centos8 に nginx1.9.1 をインストールする詳細な手順

1.17.9 本当はもっと美味しいNginx のダウンロード アドレス: https://nginx...

MySql クライアントが数秒で終了する問題を解決する (my.ini が見つからない)

問題の説明 (環境: windows7、MySql8.0)今日、MySql をインストールした後、M...

VirtualBox で作成された Debian 仮想マシンは Windows ホストとファイルを共有します

用語: 1. VM: 仮想マシンステップ: 1. Windows 10 に VirtualBox 6...

Linuxでmore、less、catコマンドを使用してファイルの内容を表示します

Linux では、cat、more、less の各コマンドを使用してファイルの内容を表示できます。c...

フレームセットの高さを設定する際のインターフェース変形の解決策

現在、プロジェクトを作成しました。インターフェースは次のとおりです。これはフレームセットを使用して行...

Vueはデジタル千単位区切り形式をグローバルに実装します

この記事の例では、Vue がデジタル 3 桁区切り形式をグローバルに実装するための具体的なコードを参...

mysql ローカルログインでポート番号を使用してログインできない問題の解決策

最近、Linux を使用してローカルにログインしていたところ、正常にログインできず、次のエラー メッ...

nginx ip ブラックリストの動的禁止の例

ウェブサイトが悪意を持ってリクエストされた場合、IP アドレスをブラックリストに登録することは重要な...

MySQL は、あるテーブルのデータに基づいて別のテーブルの特定のフィールドを更新します (SQL ステートメント)

次のコードは、MySQL が 1 つのテーブルのデータに基づいて別のテーブルのいくつかのフィールドを...

Win10でのMySQL5.7.17無料インストール版の基本設定チュートリアルについて(画像とテキスト付き)

データベース アプリケーションは、アプリケーション システムに不可欠な部分です。リレーショナル デー...

JavaScript におけるイベント バブリング メカニズムの詳細な分析

バブリングとは何ですか? DOM イベント フローには、イベント キャプチャ ステージ、ターゲット ...

Linux の cut コマンドの説明

Linux や Unix の cut コマンドは、ファイルの各行から一部を切り取って標準出力に出力す...

MySQL 8.0.18 のさまざまなバージョンのインストールとインストール中に発生した問題 (要点の要約)

概要: MYSQLの問題解決記録:どのようなインストール方法 (rpm、gz、gz.xz) を使用す...