JAvascriptで匿名function関数の後ろにカッコを付ける理由

15173 ワード

Javascriptコードライブラリ(Jquery、YUIなど)を詳しく研究した人は、きっと次のような形式の関数をたくさん見たことがあります:(function(){...}()または(function(){})()
「匿名関数の自己呼び出し」と解釈できます.つまり、匿名関数を定義し、すぐに呼び出します(匿名なので、すぐに呼び出さないと関数の参照が得られません).通常、この匿名関数の関数体は匿名の名前空間を提供することに相当するため、ユーザーがカスタマイズしたJS関数、変数、オブジェクトと衝突しないように、いくつかの大規模なJSフレームワークに適用されます.JSはネーミングスペースの定義と使用メカニズムを表示せずに提供しているが,この匿名方式はネーミングスペースの問題をうまく解決する方法であることを失わない.
だから、(function(){コード})()は関数を実行したのと同じで、匿名にすぎない.この匿名関数内でこの関数を再度呼び出すにはconstructorプロパティを呼び出す必要があります(これはObjectで定義されており、JSの継承メカニズムはJavaのようにすべてのオブジェクトがObjectクラスを継承することを保証しています).
具体的に例を挙げます.
        function test(){
            return (function(p1,p2){
                return p1+p2;
            })(1,2);
        }
        (function(){
            alert(test());
        })();//3

この匿名関数を深く検討します.
        function Foo() {
            var a = 123;
            this.a = 456;
            (function () {
                alert(a); // 123
                alert(this.a); // undefined 
            })();
        };
        var f=new Foo();
1         function Foo() {
2             var a = 123;
3             this.a = 456;
4             (function (_this) {
5                 alert(a); // 123
6                 alert(_this.a); // 456 
7             })(this);
8         };
9         var f = new Foo();

以上の2つの比較について説明します.
 
(1)匿名関数は外層署名関数(Foo)の変数(キーワードvarで定義された)に直接アクセスできるが、外層署名関数の属性(キーワードthisで定義された)にアクセスできない.
 
(2)匿名関数のthisは匿名関数オブジェクトのアドレスを指し,外層署名関数(Foo)オブジェクトのthisが指すアドレスとは異なる.
 
(3)匿名関数外層署名関数(Foo)の属性にアクセスするには,パラメータ伝達により実現できる.
1         function Foo() {
2             var a = 123;
3             this.a = 456;
4             (function (b) {
5                 alert(a); // 123
6                 alert(b); // 456 
7             })(this.a);
8         };
9         var f = new Foo();
1         (function () {
2             var a = 123;
3             this.a = 456;
4             (function () {
5                 alert(a); // 123
6                 alert(this.a); // 456 
7             })();
8         })();

以上の2つの比較について説明します.
 
(1)匿名関数は、外層匿名関数の変数に直接アクセスすることもできるし、外層匿名関数の属性に直接アクセスすることもできるが、匿名関数は外層命名関数の属性に直接アクセスすることはできない.
 
(2)以上の2つの方式で同じ機能を実現することができる.
 1         (function () {
 2             var a = 123;
 3             this.a = 456;
 4             (function () {
 5                 alert(a); // 123 
 6                 alert(this.a); // 456 
 7                 this.b = 789;
 8             })();
 9             (function () {
10                 alert(this.b); // 789 
11             })();
12         })();
13         (function () {
14             alert(this.a); // 456
15             alert(this.b); // 789 
16         })();
 1         function Foo() {
 2             var a = 123;
 3             this.a = 456;
 4             (function () {
 5                 alert(a); // 123 
 6                 alert(this.a); // undefined 
 7                 this.b = 789;
 8             })();
 9             (function () {
10                 alert(this.b); // 789 
11             })();
12         };
13         var f = new Foo();
14         (function () {
15             alert(this.a); // undefined
16             alert(this.b); // 789 
17         })();

以上の2つの比較について説明します.
 
(1)匿名関数(すなわち、2つの括弧で囲まれた部分)は、コードがどの位置に置かれているかにかかわらず、実行コンテキストに位置する.
 1         function Foo() {
 2             (function () {
 3                 this.b = 789;
 4             })();
 5             (function () {
 6                 alert(this.b); // 789
 7                 alert(b); // 789
 8                 var a = 0;
 9                 alert(a); // 0
10             })();
11         }
12         var f = new Foo();
13         (function () {
14             alert(this.b); // 789
15             alert(b); // 789
16         })();
 1         function Foo() {
 2             (function () {
 3                 this.b = 789;
 4             })();
 5             (function () {
 6                 alert(this.b); // 789
 7                 alert(b); // undefined
 8                 var b = 0;
 9                 alert(b); // 0
10             })();
11         }
12         var f = new Foo();
13         (function () {
14             alert(this.b); // 789
15             alert(b); // 789
16         })();

以上の2つの比較について説明します.
 
(1)thisの値を付けていない場合、現在の{}に同名のローカル変数が存在しない場合は、thisの処理と同等である.現在の{}に同じ名前のローカル変数がある場合は、通常の処理に従います.
 
転載先