ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript 関数クロージャーの使用に関する詳細な説明とコードの詳細な説明

JavaScript 関数クロージャーの使用に関する詳細な説明とコードの詳細な説明

伊谢尔伦
伊谢尔伦オリジナル
2017-07-25 15:04:271325ブラウズ

クロージャを表す英語はクロージャです。クロージャは JavaScript の知識の非常に重要な部分です。クロージャを使用すると、コードの量が大幅に削減され、コードがより明確に見えるなどの効果が得られます。つまり、クロージャは非常に強力です。

クロージャの意味: 端的に言えば、クロージャは関数の入れ子です。外側の関数が実行されている場合でも、内側の関数は外側の関数のすべての変数を使用できます (これには JavaScript スコープ チェーンが関係します)。

例 1

function checkClosure(){
    var str = 'rain-man';
    setTimeout(
        function(){ alert(str); } //这是一个匿名函数
    , 2000);
}
checkClosure();

この例は非常に単純に見えますが、実行プロセスを注意深く分析した後でも、まだ多くの知識ポイントがあります。checkClosure 関数の実行は瞬時に行われ (おそらく 0.00001 ミリ秒しかかかりません)、関数内で作成されます。 checkClosure の本体 変数 str が取得されます。これは、setTimeout の匿名関数が str への参照を持っているためです。 2 秒後、関数本体内の匿名関数が実行され、str が解放されます。

例 2、コードの最適化

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);   
 * }
 */

匿名関数の最大の用途は、クロージャ (JavaScript 言語の機能の 1 つ) を作成することです。また、名前空間を構築してグローバル変数の使用を減らすこともできます。

例 3:

var oEvent = {};
(function(){ 
    var addEvent = function(){ /*代码的实现省略了*/ };
    function removeEvent(){}
    oEvent.addEvent = addEvent;
    oEvent.removeEvent = removeEvent;
})();

例 4:

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

このコードの変数 1 はローカル変数 (関数内で定義されているため) であるため、外部からアクセスできません。ただし、ここでは変数 one にアクセスできる inner 関数を作成し、グローバル変数 external は inner を参照するため、outer を 3 回呼び出すと増分結果がポップアップされます。

注: クロージャにより、内部関数は親関数内の変数を参照できますが、変数は最終値です

例 6:

/**
 * <body>
 * <ul>
 *     <li>one</li>
 *     <li>two</li>
 *     <li>three</li>
 *     <li>one</li>
 * </ul>
 */
var lists = document.getElementsByTagName(&#39;li&#39;);
for(var i = 0 , len = lists.length ; i < len ; i++){
    lists[ i ].onmouseover = function(){
        alert(i);    
    };
}

解決策 1:

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

解決策 2:

var lists = document.getElementsByTagName(&#39;li&#39;);
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(&#39;li&#39;);
for(var i = 0 , len = lists.length ; i < len ; i++){
    eventListener(lists[ i ] , i);
}

以上がJavaScript 関数クロージャーの使用に関する詳細な説明とコードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。