1。匿名関数
関数は、JavaScriptで最も柔軟なオブジェクトです。ここでは、その匿名関数の目的を説明します。匿名関数:それらは関数名のない関数です。
1.1関数の定義。まず、関数の定義を簡単に紹介しましょう。ほぼ3つの方法に分割できます。
最初のもの:これも最も一般的なものです
コードコピーは次のとおりです。
関数double(x){
2 * xを返します。
}
2番目の方法:この方法は、パラメーターリストと関数本体の両方を文字列として使用する関数コンストラクターを使用します。これは非常に不便で推奨されません。
コードコピーは次のとおりです。
var double = new function( 'x'、 'return 2 * x;');
3番目のタイプ:
var double = function(x){return 2* x; }
「=」の右側の関数は匿名関数であることに注意してください。関数を作成した後、関数は可変四角に割り当てられます。
1.2匿名関数の作成
最初の方法:上記の正方形関数を定義します。これは、最も一般的に使用される方法の1つです。
2番目の方法:
コードコピーは次のとおりです。
(function(x、y){
アラート(x + y);
})(23);
ここでは、匿名関数が(最初のブラケットに)作成され、2番目のブラケットが匿名関数を呼び出してパラメーターに渡すために使用されます。
2。閉鎖
閉鎖の英語の単語は閉鎖です。これはJavaScriptの非常に重要な部分です。クロージャーを使用すると、コードの量を大幅に削減し、コードをより明確にするなどします。要するに、機能は非常に強力です。
閉鎖の意味:それを率直に言うと、閉鎖は営巣機能です。内部関数は、外側関数が実行された場合でも、外側関数のすべての変数を使用できます(これにはJavaScriptスコープチェーンが含まれます)。
例1
コードコピーは次のとおりです。
function checkclosure(){
var str = 'rain-man';
setimeout(
function(){alert(str); } //これは匿名関数です
、2000);
}
CheckCluse();
この例は非常にシンプルに見えます。その実行プロセスを慎重に分析した後、まだ多くの知識ポイントがあります。チェッククロージャー関数の実行は瞬時であり(たぶん0.00001ミリ秒かかったかもしれません)、チェッククロージャー関数の本体に変数STRが作成されます。 CheckCluserが実行された後、STRはリリースされません。これは、Settimeoutの匿名関数がSTRへの参照を持っているためです。 STRは2秒後にのみ解放されます。
例2、コードを最適化します
コードコピーは次のとおりです。
関数futimeout(x、y){
アラート(x + y);
}
関数遅延(x、y、時間){
setimeout( 'futimeout(' + x + '、' + y + ')、time);
}
/**
*上記の遅延関数は読み取りが非常に難しく、書き込みが簡単ではありませんが、閉鎖を使用すると、コードがより明確になる可能性があります
*関数遅延(x、y、時間){
* setimeout(
* 関数(){
* fortimeout(x、y)
*}
* 、 時間);
*}
*/
3。例を挙げてください
匿名関数の最大の使用は、閉鎖(JavaScript言語の機能の1つ)を作成し、グローバル変数の使用を減らすための名前空間を構築することです。
例3:
コードコピーは次のとおりです。
var oevent = {};
(関数(){
var addevent = function(){ / *コードの実装は省略されています * /};
関数removeEvent(){}
oevent.addevent = addevent;
oevent.removeevent = removeEvent;
})();
このコードでは、関数AddEventとRemoveEventは両方ともローカル変数ですが、グローバル変数Oeventを使用して使用できます。これにより、グローバル変数の使用が大幅に削減され、Webページのセキュリティが強化されます。このコードを使用します:oevent.addevent(document.getElementById( 'box')、 'click'、function(){});
例4:
コードコピーは次のとおりです。
var rainman =(function(x、y){
x + yを返します。
})(23);
/**
*最初のブラケットは読み取りのみに役立つため、次の形式で書くこともできますが、次の書き込み形式は推奨されません。
* var rainman = function(x、y){
* x + yを返します。
* }(23);
*/
ここでは、可変レインマンを作成し、匿名関数を直接呼び出すことで5に初期化します。このトリックは時々非常に実用的です。
例5:
コードコピーは次のとおりです。
var outer = null;
(関数(){
var one = 1;
関数内(){
One += 1;
アラート(1);
}
外側=内;
})();
outer(); // 2
outer(); // 3
outer(); // 4
このコードの変数はローカル変数です(関数内で定義されているため)。したがって、外部はアクセスできません。しかし、ここでは、変数の関数にアクセスできる内的関数を作成します。また、グローバル変数の外側を内側に参照するため、外側への3つの呼び出しが増分結果を表示します。
4。注意を払ってください
4.1閉鎖により、内層関数は親関数の変数を参照することができますが、変数は最終値です
例6:
コードコピーは次のとおりです。
/**
* <body>
* <ul>
* <li> 1つ</li>
* <li> 2つ</li>
* <li> 3つ</li>
* <li> 1つ</li>
* </ul>
*/
var lists = document.getElementsByTagname( 'li');
for(var i = 0、len = lists.length; i <len; i ++){
lists [i] .onmouseover = function(){
アラート(i);
};
}
マウスが各<li&rtを移動すると、要素、予想される要素の添え字の代わりに常に4をポップアップします。なぜこれがなぜですか?予防策について議論されています(最終的な価値)。明らかに、この説明は単純すぎます。マウスオーバーイベントがリスニング機能を呼び出す場合、最初に匿名関数(function(){alert(i);})内で定義されているかどうかを調べ、結果は定義されていません。したがって、上向きに見え、検索結果は定義されており、Iの値は4(ループ後のIの値)です。したがって、最終的には、各ポップアップは4です。
解決策1:
コードコピーは次のとおりです。
var lists = document.getElementsByTagname( 'li');
for(var i = 0、len = lists.length; i <len; i ++){
(function(index){
lists [index] .onmouseover = function(){
アラート(インデックス);
};
})(私);
}
解決策2:
コードコピーは次のとおりです。
var lists = document.getElementsByTagname( 'li');
for(var i = 0、len = lists.length; i <len; i ++){
[i]。$$ index = i; // DOM要素の$$インデックス属性をバインドしてインデックスを記録します
lists [i] .onmouseover = function(){
アラート(this。$$ index);
};
}
解決策3:
コードコピーは次のとおりです。
関数eventListener(list、index){
list.onmouseover = function(){
アラート(インデックス);
};
}
var lists = document.getElementsByTagname( 'li');
for(var i = 0、len = lists.length; i <len; i ++){
eventListener(lists [i]、i);
}
4.2メモリリーク
閉鎖の使用は、ブラウザのメモリリークを引き起こすのが非常に簡単です。重度の場合、ブラウザは死にます。興味がある場合は、http://www.vevb.com/article/57404.htmを参照してください