JavaScript のスコープの詳細な紹介 (コード例)

不言
リリース: 2019-03-11 16:59:20
転載
1689 人が閲覧しました

この記事では、JavaScript のスコープについて詳しく紹介 (コード例) します。一定の参考値があります。困っている友人は参照してください。お役に立てば幸いです。助けられました。

ほとんどすべてのプログラミング言語にはスコープという概念がありますが、スコープとは正確には何を指すのでしょうか?スコープとは、プログラミング言語が変数を定義するときに、変数がどのように保存され、アクセスされるかに関する一連のルールです。さまざまなプログラミング言語のルールは似ています。次に、この一連のルールがどのように設定されるかを見てみましょう。

コンパイル原理

従来のコンパイル言語では、コードが実行される前にコンパイル プロセスが行われます。

  • 単語の分割/字句解析: 単語の分割コード ステートメントを、字句単位とも呼ばれる意味のあるコード ブロックに変換します。
  • 解析/文法分析: 字句単位を、レベルごとにネストされた文法規則を含むツリー構造 (抽象構文ツリー (AST) とも呼ばれます) に変換します。
  • コード生成: AST を解析し、機械語命令を変換します。

は従来のコンパイル言語とは異なり、js のコンパイルと実行が別々に実行されるのではなく、コンパイル処理が完了した直後に実行されることがほとんどです。短時間で 制限時間内に最適なパフォーマンスを達成します。js エンジンは一般的なコンパイラーよりも複雑です。次に、js のコンパイル プロセスを見てみましょう。例として var a = 2 のコンパイルを取り上げます:

  • var a が発生すると、コンパイラはその名前の変数が同じスコープのコレクションにすでに存在するかどうかをスコープに尋ねます。そうである場合、コンパイラは宣言を無視してコンパイルを続行します。そうでない場合は、現在のスコープのコレクション内で新しい変数 a
  • を宣言するようにスコープに要求します。次に、コンパイラはエンジンのランタイム要件を生成します。これらのコードは、a=2 の代入演算を処理するために使用されます。エンジンの実行中は、まずスコープに対して、現在のスコープ セットに a という変数があるかどうかを尋ねます。そうでない場合、エンジンはこの変数を使用し、最終的に a を見つけた場合は、それに 2 を割り当てます。それ以外の場合、エンジンは例外をスローします。

字句スコープ

スコープには通常 2 つの作業モデルがあり、最初のモデルはほとんどのプログラミング言語で使用されます。使用される語彙スコープは動的スコープと呼ばれ、たとえば Bash スクリプトでは動的スコープが使用されます。字句スコープは、字句ステージで定義されるスコープです。字句スコープは、コードを記述するときに変数とブロック スコープを記述する場所によって決まります。変数定義の場所によって決まります。一方、動的スコープは、変数の使用によって決まります。決定されます。場所によって。例を見てみましょう:

function foo(a) {
  var b = a * 2;
  function bar(c) {
    console.log(a, b, c)
  }
  bar(b * 3)
}
foo(2)
ログイン後にコピー

まず、スコープが合計でいくつあるか分析してみましょう。

  1. foo 変数を含むグローバル スコープ
  2. a、b、bar 変数を含む foo 関数によって作成されるスコープ
  3. によって作成されるスコープbar 関数には c 変数があります

次に、変数検索プロセスを分析しましょう。エンジンが console.log() を実行するとき、3 つの変数 a、b への参照を見つける必要があります。 , および c. まず、最も内側の bar () スコープから開始します。エンジンは a を見つけることができないため、foo() スコープまで検索します。ここで a を見つけて検索を停止します。検索プロセスは b と同じです。 c.スコープ検索は常にランタイムの最も内側のレベルから開始され、最初に一致する変数が見つかるまで外側に向かって検索されます。

関数スコープ

関数スコープとは、この関数に属するすべての変数が関数全体のスコープ内で使用および再利用できることを意味します。これは誰もが知っていることです。定義はわかりますが、関数スコープの存在は何の役に立つのでしょうか?次に、関数スコープの秒数を見てみましょう。

内部実装の非表示

内部実装の非表示とは、非表示の目的を達成するために関数のスコープ内で変数と関数をラップすることです。なぜこれを行うのですか?ソフトウェア設計には「最小公開の原則」と呼ばれる非常に有名な原則があります。これは、モジュールやオブジェクトの API 設計など、必要なコンテンツを最小限に公開し、その他のコンテンツを隠すことを指します。関数スコープを使用して変数と関数をラップし、露出を最小限に抑え、外部からの直接アクセスを防止します。次の例を見てください:

function doSomething(a) {
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
}
  
function doSomethingElse(a) {
  return a - 1;
}
var b;
doSomething( 2 ); // 15”
ログイン後にコピー

このコードでは、doSomethingElse と b は doSomething 内でプライベートである必要がありますが、公開されると、予期しない形式で使用され、予期しない結果が生じる可能性があります。より合理的な設計は、これらのプライベート コンテンツを doSomething 内に非表示にすることです。例:

function doSomething(a) {
  function doSomethingElse(a) {
    return a - 1;
  }
  var b;
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
}
doSomething( 2 );
ログイン後にコピー

This way b Neither doSomethingElse doSomethingElse も doSomething の外部からアクセスすることはできませんが、いくつかの問題もあります。第一に、doSomething 関数はグローバル スコープで宣言されており、グローバル ロールを汚染しています。第二に、明示的な呼び出しを通じて実行する必要があります。これを回避するには? 汚染されたスコープを呼び出さずに自己実行できますか?答えは関数式です。次の例を見てください:

(function doSomething(a) {
  function doSomethingElse(a) {
    return a - 1;
  }
  var b;
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
})(2)
ログイン後にコピー

まず、関数式である (function doSomething(){}) を見てください。関数宣言とは異なり、括弧で囲まれています。 then (function doSomething(a){})() は値によって呼び出します。そのため、自己実行でき、スコープを汚染しません。コミュニティでは、この用法を表す用語 IIFE が定義されています。これは、関数の即時実行を表します。表現###

块作用域

除JavaScript外很多编程语言都支持块作用域,尽管你可能写过很伪块作用域形式的代码,最常见的就是for循环:

for(var i=0; i<10; i++) {
  console.log(i)
}
ログイン後にコピー

写这段代码通常是希望变量i在循环内部使用,但是实际上i会被绑定到外部作用域中,要确保没有在作用域的其他地方意外使用i,就只能依靠自觉,这时候块级作用域就显得尤为有用,ES6改变了现状,引入了新的let、const关键字,let关键字可以将变量绑定到所在的任意作用域中,也就是let为其声明的变量隐式地创建了作用域:

for(let i=0; i<10; i++) {
  console.log(i)        
}
console.log(i) // ReferenceError
ログイン後にコピー

这时候i就只会在for循环的内部有效


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

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