ホームページ ウェブフロントエンド jsチュートリアル JavaScriptのクロージャとは何ですか

JavaScriptのクロージャとは何ですか

Nov 20, 2017 pm 03:28 PM
javascript js 閉鎖

閉鎖とは何ですか?

クロージャとは? クロージャとは、静的言語にはない新しい機能です。しかし、クロージャは複雑すぎて理解できないものではありません。つまり、クロージャは関数のローカル変数のコレクションですが、これらのローカル変数は関数が戻った後も存在し続けます。クロージャとは、関数が戻った後に関数の「スタック」が解放されないことを意味します。また、これらの関数スタックがスタック上に割り当てられるのではなく、関数内で別の関数が定義されると、クロージャが発生することも理解できます。 。 バッグ。

クロージャ = 関数内で作成された関数 (略して内部関数) + 関数作成時の環境情報

したがって、クロージャは匿名関数と同じではありません。ただし、一部の人は関数内で作成された関数を クロージャ関数 と呼びますが、私は実際には正確ではないと思います。

次のコードを見てみましょう:

function init() {
    var name = "Zilongshanren"; // name 是在 init 函数里面创建的变量
    // displayName() 是一个内部函数,即一个闭包。注意,它不是匿名的。
    function displayName() {
        console.log(name);
    }
    //当 displayName 函数返回后,这个函数还能访问 init 函数里面定义的变量。
    return displayName;
}
var closure = init();
closure();
Zilongshanren
undefined
ログイン後にコピー

displayName は、init 関数内で作成された関数です。ここでは name 変数など、init 関数の内部スコープのすべての情報が含まれています。 displayName 関数が返されると、関数自体が作成時の環境情報、つまり init 関数の name 変数を保持します。

クロージャとは何をするのですか?

クロージャとは何かを理解した後、「これは理解するのがとても難しいのですが、何に使うのですか?」と尋ねるかもしれません。

JS にはプライベート メソッドを作成する方法がないため、Java や C++ とは異なり、プライベート プロパティやメソッドを定義するための private キーワードがありません。 JS では、関数だけが独自のスコープに属するオブジェクトを作成できます。JS にはブロック スコープがありません。これについては後ほど詳しく紹介する記事を書きたいと思います。

プログラミングのベテランなら誰でも、プログラムを上手に書くにはカプセル化と抽象化をうまく使う必要があることを知っています。プライベート プロパティとメソッドを定義できないということは、カプセル化と抽象化がまったく使用できないことを意味します。 。 。

プライベートなものを定義することはできません。すべての変数と関数はパブリックです。明らかに問題があります。グローバルは悪です。

クロージャは私たちの救世主です!

次のコードを見てみましょう:

var makeCounter = function() {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function() {
            changeBy(1);
        },
        decrement: function() {
            changeBy(-1);
        },
        value: function() {
            return privateCounter;
        }
    }
};
var counter1 = makeCounter();
var counter2 = makeCounter();
console.log(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
console.log(counter1.value()); /* Alerts 2 */
counter1.decrement();
console.log(counter1.value()); /* Alerts 1 */
console.log(counter2.value()); /* Alerts 0 */
0
2
1
0
undefined
ログイン後にコピー

ここでのprivateCounter変数とchangeByは両方ともプライベートであり、makeCounter関数の外部には完全に見えません。このようにして、makeCounter を通じて生成したオブジェクトは、そのプライベート データとプライベート メソッドをすべて非表示にします。

これを見て何か思い出しますか?

ははは、これはただのOOではないですか?データとデータを操作するためのメソッドをカプセル化し、パブリック インターフェイス呼び出しを通じてデータ処理を完了します。

もちろん、プロトタイプ継承を使用して OO を実装することもできると言うかもしれません。はい、私たちも含めて、ほとんどの人が今そうしています。ただし、コードの一部を理解するには、そのすべての継承チェーンを理解する必要があるため、継承を理解するのは常に非常に困難です。コードにバグがあると、デバッグが非常に困難になります。

まだまだ先の話ですが、クロージャを正しく使用する方法を見てみましょう。

クロージャーを正しく使用するには?

クロージャはメモリを占有し、JS エンジンの実行効率にも影響を与えるため、コードが頻繁に実行される場合は、このコードでクロージャを使用することを慎重に検討する必要があります。

オブジェクトを作成する関数を見てみましょう:

function MyObject(name, message)
 {    this.name = name.toString();  
   this.message = message.toString();   
    this.getName = function()
     {        return this.name;    };   
      this.getMessage = function() 
      {        return this.message;    };}
      var myobj = new MyObject();
var myobj = new MyObject();
ログイン後にコピー

新しいオブジェクトを生成するために呼び出されるたびに、2 つのクロージャが生成されます。プログラム内にそのような MyObject オブジェクトが何千もある場合、より多くのメモリを消費することになります。

正しいアプローチは、プロトタイプ チェーンを使用することです:

function MyObject(name, message) {
    this.name = name.toString();
    this.message = message.toString();
}
MyObject.prototype.getName = function() {
    return this.name;
};
MyObject.prototype.getMessage = function() {
    return this.message;
};
var myobj = new MyObject();
ログイン後にコピー

これで、MyObject プロトタイプには 2 つのメソッドが定義されています。new を通じてオブジェクトを作成すると、これら 2 つのメソッドはプロトタイプ上に 1 つのコピーのみを持つことになります。

クロージャのパフォーマンスはどうですか?

クロージャも関数ですが、追加の環境情報を格納するため、理論的には純粋な関数よりも多くのメモリを消費し、クロージャを解釈して実行するときに JS エンジンがより多くのメモリを消費します。ただし、両者のパフォーマンスの差は 3% ~ 5% です (これは Google から取得したデータであり、あまり正確ではない可能性があります)。

しかし、閉鎖のメリットは間違いなく大きいです。クロージャとステートレス プログラミングをもっと使用して、バグを遠ざけましょう。

クロージャを理解すると、FP パラダイムの Js クラス ライブラリのほとんどとその背後に隠された設計アイデアを理解できます。もちろん、クロージャだけでは不十分です。FP、ステートレス、ラムダ計算などの概念によって洗脳されることも必要です。

この記事を読み終えた後、皆さんが js クロージャーを理解できるようになることを願っています。

関連する推奨事項:

JS のクロージャーの簡単な説明

js のクロージャーとクラスを理解する方法

js クロージャーの簡単な理解

以上がJavaScriptのクロージャとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

推奨: 優れた JS オープンソースの顔検出および認識プロジェクト 推奨: 優れた JS オープンソースの顔検出および認識プロジェクト Apr 03, 2024 am 11:55 AM

顔の検出および認識テクノロジーは、すでに比較的成熟しており、広く使用されているテクノロジーです。現在、最も広く使用されているインターネット アプリケーション言語は JS ですが、Web フロントエンドでの顔検出と認識の実装には、バックエンドの顔認識と比較して利点と欠点があります。利点としては、ネットワーク インタラクションの削減とリアルタイム認識により、ユーザーの待ち時間が大幅に短縮され、ユーザー エクスペリエンスが向上することが挙げられます。欠点としては、モデル サイズによって制限されるため、精度も制限されることが挙げられます。 js を使用して Web 上に顔検出を実装するにはどうすればよいですか? Web 上で顔認識を実装するには、JavaScript、HTML、CSS、WebRTC など、関連するプログラミング言語とテクノロジに精通している必要があります。同時に、関連するコンピューター ビジョンと人工知能テクノロジーを習得する必要もあります。 Web 側の設計により、次の点に注意してください。

C++ ラムダ式におけるクロージャの意味は何ですか? C++ ラムダ式におけるクロージャの意味は何ですか? Apr 17, 2024 pm 06:15 PM

C++ では、クロージャは外部変数にアクセスできるラムダ式です。クロージャを作成するには、ラムダ式の外部変数をキャプチャします。クロージャには、再利用性、情報の隠蔽、評価の遅延などの利点があります。これらは、イベント ハンドラーなど、外部変数が破棄されてもクロージャが外部変数にアクセスできる現実の状況で役立ちます。

C++ラムダ式でクロージャを実装するにはどうすればよいですか? C++ラムダ式でクロージャを実装するにはどうすればよいですか? Jun 01, 2024 pm 05:50 PM

C++ ラムダ式は、関数スコープ変数を保存し、関数からアクセスできるようにするクロージャーをサポートしています。構文は [キャプチャリスト](パラメータ)->戻り値の型{関数本体} です。 Capture-list は、キャプチャする変数を定義します。[=] を使用してすべてのローカル変数を値によってキャプチャするか、[&] を使用してすべてのローカル変数を参照によってキャプチャするか、[variable1, variable2,...] を使用して特定の変数をキャプチャできます。ラムダ式はキャプチャされた変数にのみアクセスできますが、元の値を変更することはできません。

C++ 関数におけるクロージャの長所と短所は何ですか? C++ 関数におけるクロージャの長所と短所は何ですか? Apr 25, 2024 pm 01:33 PM

クロージャは、外部関数のスコープ内の変数にアクセスできる入れ子関数です。その利点には、データのカプセル化、状態の保持、および柔軟性が含まれます。デメリットとしては、メモリ消費量、パフォーマンスへの影響、デバッグの複雑さなどが挙げられます。さらに、クロージャは匿名関数を作成し、それをコールバックまたは引数として他の関数に渡すことができます。

関数ポインタとクロージャが Golang のパフォーマンスに与える影響 関数ポインタとクロージャが Golang のパフォーマンスに与える影響 Apr 15, 2024 am 10:36 AM

関数ポインタとクロージャが Go のパフォーマンスに与える影響は次のとおりです。 関数ポインタ: 直接呼び出しよりわずかに遅くなりますが、可読性と再利用性が向上します。クロージャ: 一般に遅いですが、データと動作をカプセル化します。実際のケース: 関数ポインターは並べ替えアルゴリズムを最適化でき、クロージャーはイベント ハンドラーを作成できますが、パフォーマンスの低下をもたらします。

jsとvueの関係 jsとvueの関係 Mar 11, 2024 pm 05:21 PM

js と vue の関係: 1. Web 開発の基礎としての JS、2. フロントエンド フレームワークとしての Vue.js の台頭、3. JS と Vue の補完関係、4. JS と Vue の実用化ビュー。

Java ではクロージャはどのように実装されますか? Java ではクロージャはどのように実装されますか? May 03, 2024 pm 12:48 PM

Java のクロージャを使用すると、外部関数が終了した場合でも、内部関数が外部スコープの変数にアクセスできるようになります。匿名の内部クラスを通じて実装されると、内部クラスは外部クラスへの参照を保持し、外部変数をアクティブに保ちます。クロージャによりコードの柔軟性が向上しますが、匿名の内部クラスによる外部変数への参照により、それらの変数が存続するため、メモリ リークのリスクに注意する必要があります。

PHP 関数の連鎖呼び出しとクロージャ PHP 関数の連鎖呼び出しとクロージャ Apr 13, 2024 am 11:18 AM

はい、コードの単純さと読みやすさは、連鎖呼び出しとクロージャーによって最適化できます。連鎖呼び出しは、関数呼び出しを流暢なインターフェイスにリンクします。クロージャは再利用可能なコード ブロックを作成し、関数の外の変数にアクセスします。

See all articles