1

次の例で変数スコープの概念を理解していますが、誰かが関数ラップ構文 (...)();を説明できますか?たとえば、実際の日常の JavaScript プログラミングでどのように使用しますか? PHP/Java/C# から私が知っていることではありません。

window.onload = function() {
    var i = 4;
    console.log(i); //4
    (function showIt() {
        var i = 'whatever';
        console.log(i); //whatever
    })();
    console.log(i); //4
};
4

4 に答える 4

2

これは、すでによく知っているものと同様の関数showITを ( を使用して)定義しています。function showIT() {...}最後の()は、定義されているのと同じ行で関数を直接呼び出します。それはおそらくあなたにとって新しい部分です。関数を呼び出すようshowIT()に、名前を実際の定義に置き換えると、Javascript で動作します。

于 2012-04-28T03:53:36.827 に答える
2

このフォームが役立ついくつかの方法があります。1 つは、コードのセグメントを字句的にスコープして、その内部変数とメソッドを、それを含むより大きなコード本体から分離したままにすることです。このように、これはブロック スコープを行う JavaScript の方法です。しかし、私がこの形式を使用する最も一般的な方法は、これに代わるものです。

var ret = {
    depth:0,
    initialized:false,
    helper:function() { /*help with some stuff*/ },
    initialize:function(){ /*do some initialization code*/ },
    action:function(){/*do the thing you want*/}
    destroy:function() { /*clean up*/ }
}

この形式について私を絶対に殺してしまうのは、不足している中かっこやコンマを見つけるのに非常に時間がかかることです. たとえば、action宣言の最後にコンマがないため、上記のコードは機能しません。指摘しない限り、問題を見つけるのに苦労したことでしょう。例外がスローされると、 「問題を引き起こしている」セクションではなく、ステートメント全体。これは非常に予測可能な問題であるため、回避できる可能性がある場合は、この形式を使用しなくなります。私は断る。代わりに、同じことを次のようにもっと明確に書くことができます。

var ret = (function(){
    var self = {},
        initialized = false;

    var helper = function() { /*help with some stuff*/ };

    self.depth = 0;
    self.initialize = function() {/*do some initialization*/};
    self.action = function() {/*do the thing you want*/};
    self.destroy = function() { /*clean up*/ };

    return self;
}());

私にとってのメリットは大きく2つあります。1 つ目は、欠落している中かっことコンマをより簡単に見つけることができます (例外がスローされると、行番号は欠落している領域の近くになります)。2 つ目は、一部の変数とメソッドを非公開にすることを選択でき、コードの最初のブロックの利点をすべて保持できます。

self = {}そして、この形式に与える最後のプラグインは、上記のコード (Singleton のようなもの) を、1) 外側の呼び出し中かっこを削除し、2) に変更しself = this、3)コンストラクターに変換できることです。必要に応じてreturn self、最後に を削除します。

var Ret = function(){
    var self = this,
        initialized = false;

    var helper = function() { /*help with some stuff*/ };

    self.depth = 0;
    self.initialize = function() {/*do some initialization*/};
    self.action = function() {/*do the thing you want*/};
    self.destroy = function() { /*clean up*/ };

    return self; // this is ignored by the compiler if used as a constructor
};
var ret = new Ret();
于 2012-04-28T04:22:32.637 に答える
0

JavaScript には関数リテラルがあります。関数をリテラルにして、式の結果を呼び出すだけです。あなたを混乱させているのは名前ですか?名前が使用されるのは、それ自体の本体内の関数を参照することだけであり、オプションです。(IE 8 以前とは互換性がないことに注意してください。)

于 2012-04-28T03:52:28.733 に答える
0

変数名にブロック スコープがある C とは異なり、JavaScript (Pico など) には関数スコープしかありません。

{ ... }したがって、C で使用できるように使用できない新しい名前スコープを作成する場合は、 を使用する必要があります(function() { ... })();

于 2012-04-28T03:56:30.800 に答える