JavaScript の字句スコープと object_javascript スキルの呼び出しについての深い理解
JavaScript における関数スコープ、オブジェクトの呼び出し、およびクロージャの関係は非常に微妙です。それらについての記事はたくさんありますが、なぜ多くの初心者がそれらを理解するのが難しいのかわかりません。私自身の理解をより一般的な言語で表現してみます。
スコープ Scope
JavaScript の関数は字句スコープに属します。これは、関数が実行時ではなく定義時にスコープ内で実行されることを意味します。サイの本にはこう書いてあります。しかし、「定義時」と「実行(呼び出し)時」の2つを混同している人もいます。簡単に言うと、関数 A が「定義」されているときは、関数 A(){} です。ステートメントが実行されるときは、関数が定義されたときです。また、A が呼び出されるときは、ステートメント A( )が実行されます。これら 2 つの概念は明確に区別する必要があります。
レキシカルスコープ(以下、特に指定のない限り「スコープ」と呼びます)とは何ですか?抽象的な概念ですが、端的に言えば「スコープ」であり、スコープとは英語でスコープという意味です。関数のスコープは、関数が定義されたときの「スコープ」です。つまり、この「スコープ」には外部変数の属性が含まれます。この「スコープ」は関数の内部状態に設定されます。グローバル関数が定義されると、グローバル関数の「スコープ」(関数の外層) がグローバル関数の内部状態に設定されます。入れ子関数が定義されると、入れ子関数 (外部関数) の「スコープ」が入れ子関数の内部状態に設定されます。この「内部状態」は、実際にはスコープ チェーンとして理解できます (以下を参照)。
上記のステートメントによると、関数のスコープはそれが定義されている「スコープ」であり、JavaScript の関数スコープは関数の定義時に決定されるため、静的スコープとなります。静的スコープとも呼ばれます。
Call Object
関数の呼び出しオブジェクトは動的であり、関数が呼び出されるときにインスタンス化されます。関数が定義されると、そのスコープ チェーンが決定されることはすでにわかっています。 JavaScript インタープリターが関数を呼び出すと、新しいオブジェクト (呼び出し側オブジェクト) がスコープ チェーンの先頭に追加されます。呼び出し元オブジェクトのプロパティは、arguments と呼ばれるプロパティに初期化されます。このプロパティは、関数の実際のパラメータである関数の Arguments オブジェクトを参照します。 var ステートメントで宣言されたすべてのローカル変数も、この呼び出しオブジェクトで定義されます。現時点では、呼び出し元のオブジェクトはスコープ チェーンの先頭にあり、ローカル変数、関数の仮パラメータ、および Arguments オブジェクトはすべてこの関数のスコープ内にあります。もちろん、この時点では、ローカル変数、関数の仮パラメータ、および Arguments オブジェクトによって、スコープ チェーン内の同じ名前のプロパティが上書きされます。
スコープ、スコープチェーン、呼び出し元オブジェクトの関係
私の理解では、スコープは抽象的であり、呼び出し元のオブジェクトはインスタンス化されます。
関数が定義されるとき、つまりその外部関数が実行されるとき、その関数が決定するスコープ チェーンは、実際にはその関数が呼び出されるときのその外部関数の呼び出しオブジェクト チェーンであり、そのスコープ チェーンはスコープに基づきます。定義時に決定されたチェーン (その外部関数の呼び出しオブジェクト チェーン) に、インスタンス化された呼び出しオブジェクトを加えたもの。したがって、関数のスコープ チェーンは実際には呼び出し元のオブジェクト チェーンになります。関数が呼び出されるとき、そのスコープ チェーン (または呼び出しオブジェクト チェーン) は、実際には、定義時に決定されたスコープ チェーンのスーパーセットです。
それらの間の関係は次のように表現できます: スコープ? スコープ チェーン? 呼び出し元オブジェクト。
これは複雑すぎるため、例を挙げてみましょう:
function f(x) {
var g = function () { return x; }
return g;
}
var g1 =
alert( g1()) ; //出力 1
グローバル状況を次のような大きな匿名関数とみなします:
(function() {
//これはグローバル スコープです
} )();
この例は次のようになります:
(function() {
function f(x) {
var g = function () { return x; }
return g;
}
var g1 =
alert(g1()); // 出力 1
グローバルな大きな匿名関数が定義されている場合、この関数には外層がないため、そのスコープ チェーンは空です。
グローバルで大きな匿名関数は直接実行され、グローバル スコープ チェーンには「グローバル呼び出しオブジェクト」が 1 つだけ存在します。
関数 f が定義されているとき、関数 f のスコープ チェーンはその外側のスコープ チェーン、つまり「グローバル呼び出しオブジェクト」です。
関数 f(1) が実行され、そのスコープ チェーンは、新しい f(1) 呼び出しオブジェクトに関数 f が定義されたときのスコープ チェーンを加えたものになります。つまり、「f(1) 呼び出しオブジェクト -> グローバル呼び出しオブジェクト」 。
関数 g (g1 に返されるので、g1 と名付けます) は f(1) で定義されており、そのスコープ チェーンはその外側の関数 f(1) のスコープ チェーン、つまり ' f(1 ) 呼び出しオブジェクト -> グローバル呼び出しオブジェクト'。
関数 f(1) は関数 g の定義を g1 に返します。
関数 g1 が実行され、そのスコープ チェーンは、新しい g(1) 呼び出しオブジェクトと外側の f(1) のスコープ チェーンを加えたものになります。つまり、「g1 呼び出しオブジェクト - > f(1) 呼び出しオブジェクト -」 >「グローバル呼び出しオブジェクト」。
こうして見るとよくわかります。
Closuer
クロージャを簡単に言うと、入れ子になった関数が入れ子になった関数の外側で呼び出されるときにクロージャが形成されるということです。
前の例は実際にはクロージャです。 g1 は f(1) 内で定義されていますが、f(1) が戻った後に実行されます。クロージャの効果の 1 つは、入れ子関数 f が戻った後、その内部リソースが解放されないことです。 g 関数が外部から呼び出される場合、g は f の内部変数にアクセスできます。この機能に基づいて、多くのエレガントなコードを作成できます。
たとえば、ページ上に統合カウンタを作成したい場合、クロージャを使用すると、次のように記述できます:
var counter = (function() {
var i = 0;
var fns = {"get": function( ) {return i;},
"inc": function() {return i;}};
//何かを行います
inc();
//別の処理を行います
counter.inc();
var c_value = counter.get(); // この場合、c_value は 2 になります。このように、1 つはメモリ変数 i に保持されますが、i の値はプログラム全体の他の場所で直接操作することはできず、カウンターの 2 つの操作を介してのみ操作できます。
setTimeout(fn, late) の間、関数ハンドル fn にパラメータを渡すことはできませんが、クロージャ メソッドを通じて必要なパラメータを fn の内部にバインドすることができます。
コードをコピー
このようにして、出力される値はすべて
i:5 late:6000
i:5 late:6000
i:5 late:6000
i:5 遅延:6000
代わりにクロージャを使用すると、渡されるパラメータを簡単にバインドできます:
Copy code
}
出力:
i:0 遅延:1000
i:1 遅延:2000
i:2 遅延:3000
i:3 遅延 :4000
クロージャは、イベント コールバック関数をバインドするときにもよく使用されます。同じ理由で、バインドされた関数ハンドルはパラメータとして使用できませんが、パラメータはクロージャの形式でバインドできます。
概要
関数の字句スコープとスコープ チェーンは別のものです。字句スコープは抽象概念であり、スコープ チェーンはインスタンス化された呼び出しオブジェクトのチェーンです。
関数が定義されると、その外側の関数が実行されることになります。
関数の語彙範囲は定義時に決定されますが、依然として抽象的な概念であり、インスタンス化することはできません。
関数が定義されると、インスタンス化される外部関数のスコープ チェーンという 1 つのことも決まります。 関数が複数回呼び出される場合、そのスコープ チェーンは異なります。 クロージャは強力です。 Rhinoceros の本は正しく、これらのことを理解できれば、上級 Javascript プログラマーと呼ぶことができます。これらの概念をうまく活用することで、JavaScript のさまざまなデザイン パターンを試すことができるからです。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Python を使用して Baidu Map API を呼び出し、地理的位置のクエリ機能を実装するにはどうすればよいですか?インターネットの発展に伴い、地理的位置情報の取得と活用はますます重要になっています。 Baidu Maps は、豊富な地理的位置クエリ サービスを提供する、非常に一般的で実用的な地図アプリケーションです。この記事では、Python を使用して Baidu Map API を呼び出し、地理的位置のクエリ機能を実装する方法を紹介し、コード例を添付します。 Baidu Map 開発者アカウントとアプリケーションの申請 まず、Baidu Map 開発者アカウントを取得し、アプリケーションを作成する必要があります。ログイン

PHP カメラ呼び出しスキル: 複数のカメラを切り替える方法 カメラ アプリケーションは、ビデオ会議、リアルタイム監視など、多くの Web アプリケーションの重要な部分になっています。 PHP では、さまざまなテクノロジーを使用してカメラを呼び出し、操作できます。この記事では、マルチカメラの切り替えを実装する方法に焦点を当て、読者の理解を深めるためにいくつかのサンプル コードを提供します。カメラ呼び出しの基本 PHP では、JavaScript API を呼び出すことでカメラを呼び出すことができます。具体的には、私たちは

Wedge オブジェクトは主に 2 つの方法で作成されることがわかっています。1 つは Python/CAPI を使用する方法、もう 1 つは型オブジェクトを呼び出すことによる方法です。組み込み型のインスタンス オブジェクトについては、両方のメソッドがサポートされています。たとえば、リストは [] または list() を通じて作成できます。前者は Python/CAPI で、後者は呼び出し型オブジェクトです。ただし、カスタム クラスのオブジェクトの場合は、型オブジェクトを呼び出すことによってのみ作成できます。オブジェクトを呼び出すことができる場合、そのオブジェクトは呼び出し可能ですが、それ以外の場合は呼び出し可能ではありません。オブジェクトが呼び出し可能かどうかは、対応する型オブジェクトにメソッドが定義されているかどうかによって決まります。のように

PHP 開発における外部リソースへのアクセスと呼び出しの問題を解決するには、特定のコード サンプルが必要です。PHP 開発では、API インターフェイス、サードパーティ ライブラリ、その他のサーバー リソースなどの外部リソースにアクセスして呼び出す必要がある状況によく遭遇します。 。これらの外部リソースを扱うときは、パフォーマンスと信頼性を確保しながら、安全にアクセスして呼び出す方法を考慮する必要があります。この記事では、いくつかの一般的な解決策について説明し、対応するコード例を示します。 1.curl ライブラリを使用して外部リソースを呼び出す Curl は、非常に強力なオープン ソース ライブラリです。

Python プログラミングで Baidu Map API を呼び出して地図表示機能を実装するにはどうすればよいですか?インターネットの急速な発展に伴い、地図アプリケーションは私たちの生活に欠かせないものになりました。百度地図は中国最大級の地図アプリケーションとして、地図表示機能を簡単に実現できる豊富なサービスとAPIインターフェースを提供しています。この記事では、Python プログラミングで Baidu Map API を呼び出して地図表示機能を実現する方法と、対応するコード例を紹介します。まず、を登録する必要があります

多くの友人はまだ matlab で m ファイルを呼び出す方法を知らないので、以下のエディターが matlab で m ファイルを呼び出す方法を説明しています。 1. 以下の図に示すように、まず matlab ソフトウェアを開き、メイン インターフェイスで [開く] をクリックします。 2. 次に、以下の図に示すように、開く必要がある m ファイルを選択し、「開く」を選択します。 3. 次に、以下の図に示すように、エディターで m ファイルのファイル名と変数の数を確認します。 4. 次の図に示すように、コマンド ラインで m ファイル名に続いて括弧内の変数値を入力すると、ファイルを呼び出すことができます。 5. 最後に、次の図に示すように、m ファイルを正常に呼び出すことができます。上記は、エディターによって提供された matlab で m ファイルを呼び出す方法の完全な説明です。

Java を使用して WebService を呼び出す方法の手順には、特定のコード サンプルが必要です。Web サービスは、ネットワークを介してさまざまな機能を提供する Web ベースのアプリケーション プログラム インターフェイスです。 Java 開発では、多くの場合、Web サービスを使用して他のシステムと対話する必要があります。この記事では、Java を使用して WebService を呼び出す方法と、具体的なコード例を紹介します。 1. WebService を理解する WebService は、XML 形式を使用した標準化された通信プロトコルです。

PHP を使用してナンバー プレート認識用のカメラを呼び出す方法 はじめに: 継続的な技術開発により、ナンバー プレート認識テクノロジーは、交通管理、セキュリティ監視などの分野で重要な役割を果たしています。この記事では、PHP を使用して、カメラを呼び出してナンバープレート認識機能を実装するプログラムを作成する方法を紹介します。 1. 概要 ナンバープレート認識技術には、主に画像処理と機械学習アルゴリズムが含まれます。従来のナンバー プレート認識ソリューションは、C++ や Python などのプログラミング言語を使用して開発されていました。ただし、PHP は Web 開発で広く使用されているスクリプト言語であるため、開発者は
