JavaScript の匿名関数と自己実行

Oct 13, 2016 am 10:21 AM

関数の定義は大きく 3 つの方法に分けることができます:

1 つ目: これも最も一般的な方法です

function double(x){    
    return 2 * x;       
}
ログイン後にコピー

2 つ目: このメソッドは Function コンストラクターを使用し、パラメーター リストと関数本体の両方を次のように受け取ります文字列は非常に不便なので、使用はお勧めしません。

var double = new Function('x', 'return 2 * x;');
ログイン後にコピー

3 番目のタイプ:

var double = function(x) { return 2* x; }
ログイン後にコピー

「=」の右側の関数は、関数を作成した後、変数 square に代入されることに注意してください。

匿名関数の作成

最初の方法: 上で述べたように二乗関数を定義します。これも最も一般的に使用される方法の 1 つです。

2 番目の方法:

(function(x, y){   
    alert(x + y);     
})(2, 3);
ログイン後にコピー

ここ (最初の括弧内) で匿名関数が作成され、2 番目の括弧を使用して匿名関数を呼び出し、パラメーターを渡します。括弧は式であり、式には戻り値があるため、最後に括弧のペアを追加して実行させることができます

1. 自己実行匿名関数とは何ですか。 function?

これは次のような関数を指します: (function {// code})();

2. 質問

function {// code})(); が実行できるのはなぜですか。 / code} (); しかし、エラーが報告されますか?

3. 分析

(1) まず、この 2 つの違いを理解する必要があります:
(関数 {// コード}) は式、関数 { // code} は関数宣言です。
(2) 次に、js の「プリコンパイル」の特徴:
「プリコンパイル」段階では、js は関数宣言を解釈しますが、
の場合は無視されます。 function() {// code}(); に対して実行されます。function() {//code} は「コンパイル前」段階で解釈されているため、js は function(){//code} をスキップして実行を試みます(); なのでエラーが報告されます ;
js が (function {// code})(); を実行すると、(function {// code}) は式であるため、js はそれを解決して戻り値を取得します。戻り値は関数なので、(); が見つかった場合、それが実行されます

また、関数を式に変換する方法は、必ずしもグループ化演算子 () に依存するわけではありません。 void 演算子、~ 演算子、! 演算子...…

例:

!function(){   
  alert("另类的匿名函数自执行");   
}();
ログイン後にコピー

匿名関数とクロージャ

クロージャを表す英語はクロージャです。クロージャを使用するため、これは JavaScript の知識の非常に重要な部分です。コードの量を大幅に削減し、コードをより明確に見せることができます。つまり、この関数は非常に強力です。

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

function checkClosure(){  
    var str = 'rain-man';  
    setTimeout(  
        function(){ alert(str); } //这是一个匿名函数  
    , 2000);  
}  
checkClosure();
ログイン後にコピー

この例は非常に単純に見えますが、実行プロセスを注意深く分析すると、まだ多くの知識ポイントがあります。checkClosure 関数の実行は瞬時に行われ (おそらく 0.00001 ミリ秒しかかかりません)、変数 str が関数内に作成されます。 checkClosure の本体、 setTimeout の匿名関数が str への参照を持っているため、 str は checkClosure の実行後に解放されません。 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);     
 * }  
 */
ログイン後にコピー

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

var oEvent = {};  
(function(){   
    var addEvent = function(){ /*代码的实现省略了*/ };  
    function removeEvent(){}  
     
    oEvent.addEvent = addEvent;  
    oEvent.removeEvent = removeEvent;  
})();
ログイン後にコピー

このコードでは、関数 addEvent と RemoveEvent はどちらもローカル変数ですが、グローバル変数 oEvent を通じて使用できます。これにより、グローバル変数の使用が大幅に削減され、Web ページのセキュリティが強化されます。 次のコードを使用します: oEvent.addEvent(document.getElementById('box'), 'click', function(){});

var rainman = (function(x , y){  
    return x + y;  
})(2 , 3);  
/**  
 * 也可以写成下面的形式,因为第一个括号只是帮助我们阅读,但是不推荐使用下面这种书写格式。  
 * var rainman = function(x , y){  
 *    return x + y;  
 * }(2 , 3);
ログイン後にコピー

ここでは、変数 Rainman を作成し、匿名関数を直接呼び出します。 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 回呼び出すと増分結果がポップアップされます。

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

/**  
 * <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);      
    };  
}
ログイン後にコピー

マウスを各

要素上に移動すると、期待していた要素の添字ではなく、常に 4 が表示されます。どうしてこれなの?注意事項(最終値)に記載済みです。明らかに、この説明は単純すぎます。mouseover イベントが listen 関数を呼び出すと、まず匿名関数 (function(){alert(i); }) 内を検索して、i が定義されているかどうかを確認します。 ; したがって、上方向に検索して検索します。結果は定義されており、i の値は 4 (ループ後の i の値) であるため、最終的には毎回 4 が表示されます。

解決策 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);      
    };  
}
ログイン後にコピー

2 メモリ リーク

  • クロージャを使用すると、ブラウザでメモリ リークが発生しやすくなります

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

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

    記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

    ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

    この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

    フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

    フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

    ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

    この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

    Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Mar 13, 2025 pm 12:28 PM

    この記事では、Javaのコレクションフレームワークの効果的な使用について説明します。 データ構造、パフォーマンスのニーズ、スレッドの安全性に基づいて、適切なコレクション(リスト、セット、マップ、キュー)の選択を強調しています。 コレクションの使用を効率的に最適化します

    ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:17 PM

    この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

    chart.js:パイ、ドーナツ、バブルチャートを始めます chart.js:パイ、ドーナツ、バブルチャートを始めます Mar 15, 2025 am 09:19 AM

    このチュートリアルでは、chart.jsを使用してパイ、リング、およびバブルチャートを作成する方法について説明します。以前は、4つのチャートタイプのchart.js:ラインチャートとバーチャート(チュートリアル2)、およびレーダーチャートと極地域チャート(チュートリアル3)を学びました。 パイとリングチャートを作成します パイチャートとリングチャートは、さまざまな部分に分かれている全体の割合を示すのに理想的です。たとえば、パイチャートを使用して、サファリの男性ライオン、女性ライオン、若いライオンの割合、または異なる候補者が選挙で受け取る票の割合を示すことができます。 パイチャートは、単一のパラメーターまたはデータセットの比較にのみ適しています。パイチャートのファンの角度はデータポイントの数値サイズに依存するため、パイチャートは値のあるエンティティをゼロ値で描画できないことに注意してください。これは、割合がゼロのエンティティを意味します

    初心者向けのタイプスクリプト、パート2:基本データ型 初心者向けのタイプスクリプト、パート2:基本データ型 Mar 19, 2025 am 09:10 AM

    エントリーレベルのタイプスクリプトチュートリアルをマスターしたら、TypeScriptをサポートするIDEで独自のコードを作成し、JavaScriptにコンパイルできるはずです。このチュートリアルは、TypeScriptのさまざまなデータ型に飛び込みます。 JavaScriptには、NULL、未定義、ブール値、数字、文字列、シンボル(ES6によって導入)とオブジェクトの7つのデータ型があります。 TypeScriptはこれに基づいてより多くのタイプを定義し、このチュートリアルではすべてを詳細に説明します。 ヌルデータ型 JavaScriptのように、Typescriptのnull

    See all articles