javaScriptの匿名関数とクローズドの使用

4725 ワード

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; }
右の関数は匿名関数です.関数を作成した後、変数スクウェアに与えられます.
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:
/**
 * <body>
 * <ul>
 *     <li>one</li>
 *     <li>two</li>
 *     <li>three</li>
 *     <li>one</li>
 * </ul>
 */

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);
}
回転:http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html#m0