JavaScriptのクロージャ機構を理解して使いこなす_基礎知識
偉大な同志アインシュタインはかつてこう言いました。「6 歳の子供に何かを明確に説明できないのは、あなた自身がそれを理解していないということです。」しかし、27歳の友人にクロージャとは何かを説明したところ、完全に失敗してしまいました。
これはもともと、JavaScript のクロージャーについて Stack Overflow で外国人の友人が提起した質問でした。ただし、この質問は Stack Overflow で行われたものであるため、当然のことながら、次のような古典的な回答も多くあります。
外部関数内で内部関数、つまりネストされた関数を定義すると、内部関数も外部関数の変数にアクセスできます。
function foo(x) { var tmp = 3; function bar(y) { alert(x + y + (++tmp)); } bar(10); } foo(2); // alert 16 foo(2); // alert 16 foo(2); // alert 16
このコードは正しく実行され、結果 16 が返されます。これは、bar が外部関数の変数 tmp にアクセスでき、外部関数 foo のパラメータ x にもアクセスできるためです。しかし、上の例はクロージャではありません。
クロージャを実装するには、内部関数を外部関数の戻り値として返す必要があります。つまり、内部関数は、メモリ内でアクセスされた外部関数内のすべての変数をロックします。これらの変数は、次のように bar のメモリに常駐し、ガベージ コレクターによってリサイクルされません:
function foo(x) { var tmp = 3; return function (y) { alert(x + y + (++tmp)); } } var bar = foo(2); // bar 现在是个闭包了 bar(10); // alert 16 bar(10); // alert 17 bar(10); // alert 18
上記のコードでは、bar が初めて実行されるときも、結果 16 が返されます。これは、bar は foo のスコープに直接存在しなくなりましたが、x と tmp に引き続きアクセスできるためです。つまり、tmp は bar のクロージャでロックされているため、bar が実行されるたびに tmp がインクリメントされるため、bar が 2 回目と 3 回目に実行されると、それぞれ 17 と 18 が返されます。
この例では、x は単なる純粋な値であり、foo が呼び出されるとき、値 x はパラメータとして foo にコピーされます。
しかし、JavaScript がオブジェクトを処理するときは常に参照を使用します。オブジェクトをパラメータとして foo を呼び出すと、foo に渡されるのは実際には元のオブジェクトへの参照になるため、元のオブジェクトも閉じられたことになります。 . 、次のように:
function foo(x) { var tmp = 3; return function (y) { alert(x + y + tmp++); x.memb = x.memb ? x.memb + 1 : 1; alert(x.memb); } } var age = new Number(2); var bar = foo(age); // bar 现在是个闭包了 bar(10); // alert 15 1 bar(10); // alert 16 2 bar(10); // alert 17 3
予想どおり、bar(10) が実行されるたびに、tmp がインクリメントされるだけでなく、x.memb もインクリメントされます。これは、関数本体内の x と関数外の age が同じオブジェクトを参照しているためです。
http://stackoverflow.com/questions/111102/how-do-javascript-closures-work 経由
補足: 上記の例を通して、クロージャをより明確に理解できるはずです。理解できたと思われる場合は、次のコードの実行結果を推測してみてください:
function foo(x) { var tmp = 3; return function (y) { alert(x + y + tmp++); x.memb = x.memb ? x.memb + 1 : 1; alert(x.memb); } } var age = new Number(2); var bar1 = foo(age); // bar1 现在是个闭包了 bar1(10); // alert 15 1 bar1(10); // alert 16 2 bar1(10); // alert 17 3 var bar2 = foo(age); // bar2 现在也是个闭包了 bar2(10); // alert ? ? bar2(10); // alert ? ? bar2(10); // alert ? ? bar1(10); // alert ? ? bar1(10); // alert ? ? bar1(10); // alert ? ?
実際にクロージャを使用すると、非常にエレガントなデザインを作成でき、funarg で定義されたさまざまな計算方法をカスタマイズできます。以下は、並べ替え条件関数をパラメーターとして受け入れる配列並べ替えの例です。
[1, 2, 3].sort(function (a, b) { ... // 排序条件 });
[1, 2, 3].map(function (element) { return element * 2; }); // [2, 4, 6]
someCollection.find(function (element) { return element.someProperty == 'searchCondition'; });
[1, 2, 3].forEach(function (element) { if (element % 2 != 0) { alert(element); } }); // 1, 3
(function () { alert([].join.call(arguments, ';')); // 1;2;3 }).apply(this, [1, 2, 3]);
var a = 10; setTimeout(function () { alert(a); // 10, after one second }, 1000); 还有回调函数: //... var x = 10; // only for example xmlHttpRequestObject.onreadystatechange = function () { // 当数据就绪的时候,才会调用; // 这里,不论是在哪个上下文中创建 // 此时变量“x”的值已经存在了 alert(x); // 10 }; //...
var foo = {}; // 初始化 (function (object) { var x = 10; object.getX = function _getX() { return x; }; })(foo); alert(foo.getX()); // 获得闭包 "x" – 10

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

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

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

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

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

ホットトピック











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

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

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

タイトル: クロージャによって引き起こされるメモリ リークと解決策 はじめに: クロージャは JavaScript における非常に一般的な概念であり、内部関数が外部関数の変数にアクセスできるようにします。ただし、クロージャを誤って使用すると、メモリ リークが発生する可能性があります。この記事では、クロージャによって引き起こされるメモリ リークの問題を調査し、解決策と具体的なコード例を提供します。 1. クロージャによるメモリリーク クロージャの特徴は、内部関数が外部関数の変数にアクセスできることです。つまり、クロージャ内で参照される変数はガベージコレクションされません。不適切に使用すると、

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

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

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

匿名関数は簡潔で匿名ですが、可読性が低く、デバッグが困難です。クロージャはデータをカプセル化して状態を管理できますが、メモリの消費と循環参照が発生する可能性があります。実際のケース: 匿名関数は単純な数値処理に使用でき、クロージャは状態管理を実装できます。
