初めて jQuery に出会ったとき1 年前、私も他の人たちと同じように、ソース コードがどのようなものになるのかを見るのがとても楽しみでした。しかし、初めてソースコードを見たとき、私は混乱しました。匿名関数が 1 つしかなく、それが実行されているのを誰も見ていないのに (もちろん実行されています...)、なぜ jQuery のような関数ライブラリが存在するのでしょうか?そこで、質問があって CSDN に来ました。その結果、今では多くの人がそれをはっきりと理解していると思います(私の後にたくさんの人が来ているので、笑〜)。匿名関数を括弧で囲み、その後に括弧を続けると、匿名関数をすぐに実行できます。すごいですね!
ふふ!ナンセンスな話はこれくらいです。このセクションで取り上げた jQuery スニペットは、すぐに実行される匿名関数のセットです。この使用法はフォーラムでも激しい議論を引き起こしました - このコードはクロージャに属しているのでしょうか?この質問を念頭に置いて、私たちは基本から始めて、各重要な要素を分析し、独自の答えを見つけます。 (はい、私自身の答えです。私の意見では、すべての理論は単なる形式にすぎません。アプリケーションの実装に役立つ限り、それが望ましいです。黒猫と白猫、ネズミを捕まえるのは良い猫です! )
もちろん、これは単なる数学的な定義です。ただし、コンピューター プログラミング言語でも、関数の定義は似ています。コンピューターの関数は数学的定義の記述に似ていることは誰もが知っているため、これはコードで設定された論理演算を通じて入力データを処理し、一意の出力を返すコードの組み合わせブロックのセットです。 ——もちろん、特殊な場合は、入力データが空であるか、出力データが空であるか、あるいは両方が空である場合です。
ブラウザーにポップアップが表示されます。プロンプト ボックス、プロンプト あなたの abc は Function オブジェクトです。では、Function オブジェクトとは正確には何でしょうか?
Function オブジェクトは JavaScript の固有オブジェクトです。すべての関数は実際には Function オブジェクトです。この側面の議論は次のトピックセクションに譲ります。まず、Function オブジェクトがコンストラクターを直接使用して新しい関数を作成できるかどうかを見てみましょう。答えは「はい」です。例:
alert(typeof function(x,y){return x y;}) ;// "関数"
alert(typeof new Function("x","y","return x*y;"))// "関数"
alert(typeof function(){}); // "関数"alert(typeof function(x,y){return x y;});// "関数"alert(typeof new Function("x","y","return x*y;"))/ / "関数 "
これらはすべて Function オブジェクトであることが簡単にわかります。つまり、すべて関数ですが、名前がないという 1 つの機能があります。したがって、これらを「匿名関数」と呼びます。しかし、「名前」がないからといって、それを見つける方法はありません。これは、匿名関数をどのように呼び出すかという問題につながります。
匿名関数の呼び出し
関数を呼び出すには、関数を見つけて参照する方法が必要です。したがって、名前を見つける必要があります。例:
var abc=function(x ,y){
return x y;
}
alert(abc(2,3)); // "5"
var abc=function(x,y){ return x y } (abc(2 ,3)); // "5"
上記の操作は、実際には、別の方法で関数を定義することと同じです。たとえば、DOM 要素のイベント処理関数を設定する場合、通常は名前を付けず、対応するイベント参照に匿名関数を与えます。
実際には、匿名関数を呼び出す別の方法があります。これは、先ほど見た jQuery フラグメントです。() を使用して匿名関数を囲み、括弧のペア (パラメーター リストを含む) を追加します。もう一度次の例を見てみましょう:
alert( (function(x,y){return x y;})(2,3));// "5"
alert((new Function("x","y"," return x*y;") )(2,3));// "6"
alert((function(x,y){return x y;})(2,3));// "5" alert((new Function(" x","y","return x*y;"))(2,3));// "6"
なぜこれなのか疑問に思う人も多いかもしれませんメソッドは正常に呼び出すことができますか? 毛織物?このアプリケーションが奇妙だと思われる方は、以下の私の説明を読んでください。
括弧の役割を知っていますか?かっこを使用すると式の組み合わせをブロックに分割でき、各ブロック、つまりかっこの各ペアに戻り値があります。この戻り値は、実際には括弧内の式の戻り値です。したがって、一対のかっこを使用して無名関数を囲むと、一対のかっこが実際に返すものは、匿名関数の Function オブジェクトになります。したがって、かっこのペアと匿名関数は、名前付き関数と同様に参照されます。そこで、この参照変数の後にパラメータリストを追加すると、通常の関数の呼び出し形式になります。
上記の文章表現を理解できるかわかりませんが、それでも理解できない場合は、次のコードを見てください。
var abc=function(x,y) {return x y ;};// 無名関数オブジェクトを abc に代入します
// abc のコンストラクタは無名関数のコンストラクタと同じです。つまり、2 つの関数の実装は同じです。
alert((abc).constructor==(function(x,y){return x y;}).constructor);
var abc=function(x,y){return x y;};//匿名関数オブジェクトは abc に割り当てられます // abc のコンストラクターは、匿名関数のコンストラクターと同じです。つまり、2 つの関数の実装は同じです。 alert((abc).constructor==(function(x,y){return x y;}).constructor);
PS: コンストラクターとは、オブジェクトを作成する関数を指します。つまり、関数オブジェクトによって表される関数本体です。
つまり、これ (括弧で囲まれた無名関数) を括弧の式によって返される関数オブジェクトとして理解すれば、この関数オブジェクトに対して通常のパラメーター リスト呼び出しを行うことができます。 (以前ここで間違いを犯しました。関数式のみを使用して関数を直接呼び出すことはできません。匿名関数の括弧を削除するには、式を代入する必要があります。つまり、(function(){alert(1)})() は次のとおりです。 =function(){alert(1)}() と同じです。a= を削除することはできません。)
Closure
クロージャとは何ですか?クロージャとは、第 1 レベルの関数の存在を許可する特定のプログラミング言語のコード ブロックを指し、第 1 レベルの関数で定義された自由変数は、第 1 レベルの関数が解放されるまで解放されません。第 1 レベルの関数の外側に適用された自由変数が解放されました。
どうやって?見終わった後は汗だくでしょうね…大丈夫ですよ、私もです(それは分かっていますが、私の表現力の問題です)。より簡単に説明しましょう。クロージャは実際には、関数をオブジェクトとして扱うことを可能にするプログラミング言語を指し、オブジェクト内の操作などを関数内のインスタンスを定義するために移動できます。 ) 変数があり、これらの変数は関数のインスタンス オブジェクトが破棄されるまで関数内に保存でき、他のコード ブロックは何らかの方法でこれらのインスタンス (ローカル) 変数の値を取得し、アプリケーションを拡張できます。
このように説明しても明確になるかどうかはわかりませんが、まだ理解できない場合は、もう一度単純化してみましょう。クロージャは実際には、コードを許可するプログラミング言語で定義されたローカル部分を指します。実行中の関数を呼び出します。
次に例を見てみましょう:
var abc=function(y){
var x=y;// これはローカル変数です
return function(){
alert(x );// これは、クロージャ特徴量はレベル関数ローカル変数と呼ばれます // "5" "5"
abc();// "6" "4"
abc();// "7" "3"
alert(x);// エラー! 「x」は定義されていません!
var abc=function(y){ var x=y;// これはローカル変数です return function(){ alter(x);// これは、第 1 レベル関数のローカル変数の x です。クロージャ機能が呼び出され、それに対して操作しますalert(y--);//参照されるパラメータ変数も自由変数です}}(5);//abc() を初期化します;// "5" "5" abc( );// " 6" "4" abc();// "7" "3" alter(x);// エラー! 「x」は定義されていません!
これを見ると、jQuery コード スニペットが閉じられているかどうかわかりますか?
私の理解を使ってみましょう。クロージャ機能が適用されるかどうかにかかわらず、コードに最も重要な要素、つまり破棄されていないローカル変数が含まれているかどうかを判断する必要があります。したがって、実装のない匿名関数はクロージャ機能を適用できないことは明らかです。しかし、匿名関数に実装がある場合はどうなるでしょうか?次に、破棄されていないローカル変数がその実装で使用されているかどうかを確認する必要があります。では、冒頭の記事の jQuery コード スニペットでは、JS のどのような機能が使用されているかと尋ねると、?そうなると、それは単なる匿名関数と匿名関数呼び出しになります。ただし、これはクロージャのプロパティを意味しており、クロージャはいつでも適用できます。なぜなら、JS にはこの機能が備わっているからです。 (これは私の理解です。あなたの理解も知りたいです。コミュニケーション大歓迎です!クローズについては、機会があれば独立して別のトピックを開きましょう!)