JavaScriptの匿名関数とクローズドについて詳しく説明します.

5172 ワード

1、匿名関数はJavaScriptの中で最も柔軟な対象であり、ここではその匿名関数の用途を説明するだけである.匿名関数:関数名がない関数です.
1.1関数の定義は、まず簡単に関数の定義を紹介します.大きく三つの方法に分けられます.
第一種類:これも最も一般的なものです.
 
  
function double(x){
    return 2 * x;  
}
第二の方法:この方法はFunctionコンストラクタを使用しており、パラメータリストと関数体を文字列として使用するのは不便で、使用を推奨しない.
 
  
var double = new Function('x', 'return 2 * x;');
第三種類:
var double=function(x){return 2**x}「=」の右の関数は匿名関数であり、関数を作成した後、また変数squareに関数を与えました.
1.2匿名関数の作成
第一の方法:上で述べたスクウェア関数の定義です.これも一番よく使われている方法の一つです.
第二の方法:
 
  
(function(x, y){
    alert(x + y); 
})(2, 3);
ここでは匿名関数(第一括弧内)が作成され、第二括弧は匿名関数を呼び出してパラメータに入る.
2、クローズドクローズの英単語はクローズアップです.これはJavaScriptの中で非常に重要な知識です.クローズドを使うとコード量を大幅に減らすことができますので、コードをより明確に見せるなど、とにかく機能が非常に強いです.
クローズドの意味:クローズドパックは関数の入れ子であり、内部の関数は外層関数のすべての変数を使用しても、外層関数はすでに実行済みである(これはJavaScript作用領域チェーンに関連する).
例1
 
  
function checkClosure(){
    var str = 'rain-man';
    setTimeout(
        function(){ alert(str); } //
    , 2000);
}
checkClosure();
この例は非常に簡単に見えるが、その実行過程を詳しく分析すると、多くの知識点がある.checkCloosure関数の実行は瞬間的(おそらく0.00001ミリ秒)であり、checkCloureの関数の中に変数strが作成され、checkCloureの実行が終わった後、strは解放されなかった.これは、setTimeout内の匿名関数がこのstrに対する参照が存在するためである.2秒後には関数の匿名関数が実行され、strが解放される.
例二、最適化コード
 
  
function forTimeout(x, y){
    alert(x + y);
}
function delay(x , y  , time){
    setTimeout('forTimeout(' +  x + ',' +  y + ')' , time);   
}
/**
 * delay , ,
 * function delay(x , y , time){
 *     setTimeout(
 *         function(){
 *             forTimeout(x , y)
 *         }         
 *     , time);  
 * }
 */
 
3、匿名関数を例に挙げる最大の用途はクローズドパケットを作成することであり(これはJavaScript言語の特性の一つである)、グローバル変数の使用を低減するために名前空間を構築することもできる.
例3:
 
  
var oEvent = {};
(function(){
    var addEvent = function(){ /* */ };
    function removeEvent(){}

    oEvent.addEvent = addEvent;
    oEvent.removeEvent = removeEvent;
})();

このコードの中で関数addEventとremoveEveveveveveveveventは局所変数ですが、大域変数oEventを通じてそれを使うことができます.これは大域変数の使用を大幅に減らして、ウェブページの安全性を高めます.私たちはこのコードを使いたいです.oEvent.addEvent(document.getElement ById),'click',function();;
例四:
 
  
var rainman = (function(x , y){
    return x + y;
})(2 , 3);
/**
 * , , 。
 * var rainman = function(x , y){
 *    return x + y;
 * }(2 , 3);
 */
ここでは変数Rainmanを作成し、直接に匿名関数を呼び出して5に初期化します.このような小テクニックは時に非常に実用的です.
例5:
 
  
var outer = null;
(function(){
    var one = 1;
    function inner (){
        one += 1;
        alert(one);
    }
    outer = inner;
})();
outer();    //2
outer();    //3
outer();    //4
このコードの変数oneは局所変数です.外部はアクセスできません.ここではinner関数を作成しました.inner関数は変数oneにアクセスできるものです.グローバル変数outerはinnerを参照していますので、3回の呼び出しでouterはインクリメントされた結果をポップアップします.
4、注意4.1閉梱は親関数の変数を内層関数で参照することができますが、この変数は最終値です.
例6:
 
  
/**
 *
 *

     *    
  • one

  •  *    
  • two

  •  *    
  • three

  •  *    
  • one

  •  *

 */

var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++){
    lists[ i ].onmouseover = function(){
        alert(i);   
    };
}

マウスがすべてのマウスを移動したときに発見されます.
解決方法一:
 
  
var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++){
    (function(index){
        lists[ index ].onmouseover = function(){
            alert(index);   
        };                   
    })(i);
}
解決方法二:
 
  
var lists = document.getElementsByTagName('li');
for(var i = 0, len = lists.length; i < len; i++){
    lists[ i ].$$index = i;    // Dom $$index
    lists[ i ].onmouseover = function(){
        alert(this.$$index);   
    };
}
解決方法3:
 
  
function eventListener(list, index){
    list.onmouseover = function(){
        alert(index);
    };
}
var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++){
    eventListener(lists[ i ] , i);
}
4.2メモリリーク
クローズドバッグを使うとブラウザのメモリが漏れやすくなります.深刻な場合はブラウザが止まります.興味があれば参考にしてください.