ホームページ ウェブフロントエンド jsチュートリアル JavaScript の字句スコープと object_javascript スキルの呼び出しについての深い理解

JavaScript の字句スコープと object_javascript スキルの呼び出しについての深い理解

May 16, 2016 pm 05:47 PM
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 の内部にバインドすることができます。



コードをコピー
コードは次のとおりです。 for(var i=0,lay= 1000; isetTimeout(function() { console.log('i:' i " 遅延:" 遅延);
}, 遅延); 🎜>}


このようにして、出力される値はすべて
i:5 late:6000
i:5 late:6000
i:5 late:6000
i:5 遅延:6000
i:5 遅延:6000
代わりにクロージャを使用すると、渡されるパラメータを簡単にバインドできます:




Copy code

コードは次のとおりです: for(var i=0, late=1000; i (function(a , _lay) { setTimeout(function() { console.log('i:' a " late:" _delivery);
}, _lay);
}) (i, 遅延) ;
}


出力:
i:0 遅延:1000
i:1 遅延:2000
i:2 遅延:3000
i:3 遅延 :4000
i:4 遅延:5000
クロージャは、イベント コールバック関数をバインドするときにもよく使用されます。同じ理由で、バインドされた関数ハンドルはパラメータとして使用できませんが、パラメータはクロージャの形式でバインドできます。

概要

関数の字句スコープとスコープ チェーンは別のものです。字句スコープは抽象概念であり、スコープ チェーンはインスタンス化された呼び出しオブジェクトのチェーンです。
関数が定義されると、その外側の関数が実行されることになります。
関数の語彙範囲は定義時に決定されますが、依然として抽象的な概念であり、インスタンス化することはできません。
関数が定義されると、インスタンス化される外部関数のスコープ チェーンという 1 つのことも決まります。 関数が複数回呼び出される場合、そのスコープ チェーンは異なります。 クロージャは強力です。 Rhinoceros の本は正しく、これらのことを理解できれば、上級 Javascript プログラマーと呼ぶことができます。これらの概念をうまく活用することで、JavaScript のさまざまなデザイン パターンを試すことができるからです。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Python を使用して Baidu Map API を呼び出し、地理的位置のクエリ機能を実装するにはどうすればよいですか? Python を使用して Baidu Map API を呼び出し、地理的位置のクエリ機能を実装するにはどうすればよいですか? Jul 31, 2023 pm 03:01 PM

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

PHP カメラ呼び出しスキル: マルチカメラ切り替えの実装方法 PHP カメラ呼び出しスキル: マルチカメラ切り替えの実装方法 Aug 04, 2023 pm 07:07 PM

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

ソースコードの探索: Python ではオブジェクトはどのように呼び出されますか? ソースコードの探索: Python ではオブジェクトはどのように呼び出されますか? May 11, 2023 am 11:46 AM

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

PHP開発における外部リソースへのアクセスと呼び出しを解決する方法 PHP開発における外部リソースへのアクセスと呼び出しを解決する方法 Oct 08, 2023 am 11:01 AM

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

Python プログラミングで Baidu Map API を呼び出して地図表示機能を実装するにはどうすればよいですか? Python プログラミングで Baidu Map API を呼び出して地図表示機能を実装するにはどうすればよいですか? Aug 02, 2023 pm 08:27 PM

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

matlab が m ファイルを呼び出す方法-matlab で m ファイルを呼び出す方法 matlab が m ファイルを呼び出す方法-matlab で m ファイルを呼び出す方法 Mar 04, 2024 pm 01:49 PM

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

Javaを使用してWebServiceを呼び出す方法 Javaを使用してWebServiceを呼び出す方法 Dec 29, 2023 pm 02:32 PM

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

PHP を介してナンバープレート認識のためにカメラを呼び出す方法 PHP を介してナンバープレート認識のためにカメラを呼び出す方法 Aug 02, 2023 pm 01:57 PM

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

See all articles