JavaScriptクロージャ_JavaScriptスキルの詳しい説明
インターネット上でクロージャに関する概念や記事を読んだ後、この問題を自分自身で整理してみたいと思います。
Q: クロージャとは何ですか?
回答: クロージャとは、JavaScript において、外部関数が返された後 (サポート終了) であっても、内部関数がその内部関数が配置されている外部関数で宣言されたパラメーターと変数に常にアクセスできることを意味します。
クロージャーの問題に遭遇したのはこれが初めてです
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <title>闭包循环问题</title> <style type="text/css"> p {background:#ccc; width: 300px; height: 100px;} </style> </head> <body> <p id="p0">段落0</p> <p id="p1">段落1</p> <p id="p2">段落2</p> <p id="p3">段落3</p> <p id="p4">段落4</p> <script type="text/javascript"> for( var i=0; i<5; i++ ) { document.getElementById("p"+i).onclick=function() { alert(i); //访问了父函数的变量i, 闭包 }; }; </script> </body> </html>
これまでに使用したことがない場合は、段落をクリックすると、この段落に対応する番号 0、1、2、3、4 がポップアップ表示されると考えるかもしれません。しかし実際には、それらはすべて 5 つ現れます。
この問題についてオンラインで議論しているブログは数多くあり、対応する番号をポップアップ表示するためのさまざまな方法が提供されています。
解決策 1: 変数 i を対応する段落の属性に保存します
var pAry = document.getElementsByTagName("p"); for( var i=0; i< 5; i++ ) { pAry[i].no = i; pAry[i].onclick = function() { alert(this.no); } };
解決策 2: クロージャーの層を追加し、関数パラメーターの形式で i を内部関数に渡します
var pAry = document.getElementsByTagName("p"); for( var i=0; i< 5; i++ ) { pAry[i].no = i; pAry[i].onclick = function() { alert(this.no); } };
これによって引き起こされるクロージャの問題について、インターネット上では「変数 i はポインタまたは変数アドレスとして関数に格納される」と言われていますが、これはすべてポインタに関係しています。 。 。 。次に、さらに探索します。
Explore 1、戻り値は
ではなく 10 です
(function test() { var temp =10; for(var i=0; i< 5; i++ ){ document.getElementById("p"+i).onclick=function() { alert(temp); //访问了父函数的变量temp, 闭包 } }; temp=20; })();
2 を探索し、10 を一度返し、その後 20 を返します
(function test() { var temp =10; for( var i=0; i< 5; i++ ) { document.getElementById("p"+i).onclick=function() { alert(temp); //访问了父函数的变量i, 闭包 } if(i===1){ alert(temp); } }; temp=20; })();
1 と 2 の検討から、関数と同じレベルの変数が関数内でアクセスされる場合、その変数はメモリ内に常駐すると結論付けることができます。この変数にアクセスすると、基本的に変数
のアドレスにアクセスします。その後、「JS クロージャー内のこのオブジェクト」に関する別の記事を読みました。この問題について引き続き議論しましょう。
// js闭包this对象1 var name = 'The Window'; var object = { name : 'My Object', getNameFunc1 : function(){ // return this.name; console.log(this);//object return function(){//闭包,访问的便是全局变量的了,this指windows console.log(this);//windows return this.name; //The Window } }, getNameFunc2 : function(){ return this.name;//访问的是object }, aa:function(){ alert(22); } }; alert(object.getNameFunc1()());//弹出“The Window”
質問: では、なぜ匿名関数はそのスコープを含む this オブジェクトを取得しないのでしょうか?
回答: すべての関数は、呼び出されるときに、this と引数という 2 つの特別な変数を自動的に取得します。 これら 2 つの変数を検索する場合、内部関数はアクティブなオブジェクトに検索を指示するため、外部関数でこれら 2 つの変数に直接アクセスすることはできません。
ただし、これは次のコードで実行できます (外部関数の変数に直接アクセスします):
// js闭包this对象2 var name = 'The Window'; var object = { name : 'My Object', getNameFunc : function(){ var that = this; console.log(this);//输出的是object return function(){ console.log(this);//输出的仍然是Windows return that.name; }; } }; alert(object.getNameFunc()());//弹出“My Object”
違いは、関数が戻った後でも this オブジェクトが that 変数に割り当てられるため、オブジェクトが返されることです。
クロージャについてたくさん書いてきたので、クロージャの有用性について触れておきます。そうしないと、クロージャをいじり続けるのは悪い人になります。
この典型的なクロージャの例を見てください:
function A(){ var a=1; function B(){ return a; }; return B; }; var C=A();//C取得A的子作用域B的访问接口 console.log(C());//1 C能访问到B的父级作用域中的变量a
他のスコープが子スコープのアクセス インターフェイスを取得できる限り、他のスコープは子スコープの親スコープの変数にアクセスする方法を持ちます。この場合、将来特定の関数の値にアクセスする必要がある場合に非常に役立ちます。
上記のコードの多くは実際にオンラインで見つけたもので、私が理解した内容と読んだプロセスを要約したものです。

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

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

Go 言語の関数クロージャは単体テストで重要な役割を果たします。 値のキャプチャ: クロージャは外側のスコープ内の変数にアクセスできるため、テスト パラメータをキャプチャしてネストされた関数で再利用できます。テスト コードの簡素化: クロージャは値をキャプチャすることで、ループごとにパラメーターを繰り返し設定する必要性を排除し、テスト コードを簡素化します。可読性の向上: クロージャを使用してテスト ロジックを整理し、テスト コードをより明確で読みやすくします。
