JavaScript スコープの包括的な分析 (コード付き)

不言
リリース: 2019-04-03 10:27:59
転載
2143 人が閲覧しました

この記事は、JavaScript スコープの包括的な分析 (コード付き) を提供します。これには特定の参考値があります。必要な友人は参照できます。お役に立てば幸いです。ヘルプ。

スコープは変数のライフサイクルと可視性を決定します。変数はスコープの外では見えません。

JavaScript のスコープには、モジュール スコープ、関数スコープ、ブロック スコープ、字句スコープ、グローバル スコープが含まれます。

グローバル スコープ

関数、ブロック、またはモジュールのスコープ外で定義された変数には、グローバル スコープがあります。グローバル変数はプログラム内のどこからでもアクセスできます。

モジュール システムが有効になっている場合、グローバル変数の作成はより困難になりますが、それでも実行できます。関数の外で宣言する必要がある変数を HTML で定義できるため、グローバル変数を作成できます。

<script>
  let GLOBAL_DATA = { value : 1};
</script>
console.log(GLOBAL_DATA);
ログイン後にコピー

モジュール システムがない場合、グローバル変数の作成がはるかに簡単になります。ファイル内の関数の外で宣言された変数はグローバル変数です。

グローバル変数は、プログラムのライフサイクル全体を通じて実行されます。

グローバル変数を作成する別の方法は、プログラム内の任意の場所で window グローバル オブジェクトを使用することです。

window.GLOBAL_DATA = { value: 1 };
ログイン後にコピー

この方法では、GLOBAL_DATA 変数は次のようになります。どこにでも 。

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

しかし、このアプローチが良くないこともわかっています。

モジュール スコープ

モジュールが有効になっていない場合、すべての関数の外で宣言された変数はグローバル変数になります。モジュールでは、関数の外で宣言された変数は隠されており、明示的にエクスポートしない限り、他のモジュールでは使用できません。

エクスポートにより、関数またはオブジェクトを他のモジュールで使用できるようになります。この例では、モジュール ファイル sequence.js から関数をエクスポートしました。

// in sequence.js
export { sequence, toList, take };
ログイン後にコピー

現在のモジュールは、インポートすることで他のモジュールの関数やオブジェクトを使用できます。

import { sequence, toList, toList } from "./sequence";
ログイン後にコピー

モジュールは、インポートされたデータを入力として受け取り、エクスポートされたデータを返す自動的に実行される関数としてある程度考えることができます。

関数スコープ

関数スコープとは、関数内で定義されたパラメーターと変数が関数内のどこにでも表示されるが、関数の外部には表示されないことを意味します。

次は、IIFE と呼ばれる自動実行される関数です。

(function autoexecute() {
    let x = 1;
})();
console.log(x);
//Uncaught ReferenceError: x is not defined
ログイン後にコピー

IIFE は、関数式の即時呼び出しを意味します。これは、定義直後に実行される関数です。

var で宣言された変数には関数スコープのみがあります。さらに重要なのは、var で宣言された変数はスコープの最上位に昇格されることです。こうすることで、宣言する前にアクセスできるようになります。次のコードを見てください:

function doSomething(){
  console.log(x);
  var x = 1;
}
doSomething(); //undefined
ログイン後にコピー

このようなことは let では起こりません。 let で宣言された変数は、定義された後でのみアクセスできます。

function doSomething(){
  console.log(x);
  let x = 1;
}
doSomething();
//Uncaught ReferenceError: x is not defined
ログイン後にコピー

var で宣言された変数は、同じスコープ内で複数回再宣言できます:

function doSomething(){
  var x = 1
  var x = 2;
  console.log(x);
}
doSomething();
ログイン後にコピー

使用 let または const宣言された変数を同じスコープ内で再宣言することはできません。

function doSomething(){
  let x = 1
  let x = 2;
}
//Uncaught SyntaxError: Identifier 'x' has already been declared
ログイン後にコピー

var は廃止され始めているため、これについては気にしなくてもよいかもしれません。

ブロック スコープ

ブロック スコープは中括弧で定義されます。 {} で区切られます。

let

および const で宣言された変数はブロック スコープによって制約され、変数が定義されているブロック内でのみアクセスできます。

let

ブロック スコープに関する次のコードを考えてみましょう: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">let x = 1; {    let x = 2; } console.log(x); //1</pre><div class="contentsignin">ログイン後にコピー</div></div>対照的に、

var

宣言はブロック スコープによって束縛されません: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var x = 1; {    var x = 2; } console.log(x); //2</pre><div class="contentsignin">ログイン後にコピー</div></div> もう 1 つの一般的な問題は、ループ内で

setTimeout()

のような非同期操作を使用することです。次のループ コードは、数字 5 を 5 回表示します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">(function run(){     for(var i=0; i&lt;5; i++){         setTimeout(function logValue(){             console.log(i);         //5         }, 100);     } })();</pre><div class="contentsignin">ログイン後にコピー</div></div>

let

宣言を含む for ループ ステートメントは、ループするたびに新しい変数を作成し、ブロック スコープに設定します。コードの次のループでは、0 1 2 3 4 5 が表示されます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">(function run(){   for(let i=0; i&lt;5; i++){     setTimeout(function log(){       console.log(i); //0 1 2 3 4     }, 100);   } })();</pre><div class="contentsignin">ログイン後にコピー</div></div> 字句スコープ

字句スコープとは、内部関数が定義されている外部スコープにアクセスするための内部関数の機能です。

このコードを見てください:

(function autorun(){
    let x = 1;
    function log(){
      console.log(x);
    };
    
    function run(fn){
      let x = 100;
      fn();
    }
    
    run(log);//1
})();
ログイン後にコピー

log

この関数はクロージャです。これは、run() 関数の x 変数ではなく、親関数 autorun() の #xx 変数を参照します。 クロージャー関数は、それ自体のスコープではなく、それが作成されたスコープにアクセスできます。

autorun()

のローカル関数スコープは、

log() 関数の字句スコープです。 スコープ チェーン

各スコープには、親スコープへのリンクがあります。変数を使用する場合、JavaScript は要求された変数が見つかるまで、またはグローバル スコープ (つまり、スコープ チェーンの終わり) に到達するまでスコープ チェーンを調べます。

次の例を見てください:

let x0 = 0;
(function autorun1(){
 let x1 = 1;
  
 (function autorun2(){
   let x2 = 2;
  
   (function autorun3(){
     let x3 = 3;
      
     console.log(x0 + " " + x1 + " " + x2 + " " + x3);//0 1 2 3
    })();
  })();
})();
ログイン後にコピー

内部関数
autorun3()

はローカル

x3 変数にアクセスできます。変数 x1x2 およびグローバル変数 x0 は、外部関数からもアクセスできます。 変数が見つからない場合、厳密モードではエラーが返されます。

"use strict";
x = 1;
console.log(x)
//Uncaught ReferenceError: x is not defined
ログイン後にコピー
非厳格モードは「いい加減モード」とも呼ばれ、グローバル変数を急いで作成します。

x = 1;
console.log(x); //1
ログイン後にコピー
概要

グローバル スコープで定義された変数は、プログラム内のどこでも使用できます。

モジュールでは、関数の外で宣言された変数は隠されており、明示的にエクスポートしない限り他のモジュールで使用できません。

関数スコープとは、関数内で定義されたパラメーターと変数が関数内のどこでも参照できることを意味します。

変数は let および const で宣言されます。 ブロック スコープがあります。 。 var にはブロック スコープがありません。

【関連する推奨事項: JavaScript ビデオ チュートリアル ]

以上がJavaScript スコープの包括的な分析 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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