0

「Javascript: The Definitive Guide」6E を読んでいて、次の例に出くわしました。

  var cookies = (function() {
    var cookies = {};
    var all = document.cookie;
    if ( all === "" )
      return cookies;
    var list = all.split("; ");
    for ( var i = 0; i < list.length; i++ )
    {
      var cookie = list[ i ];
      var p = cookie.indexOf( "=" );
      var name = cookie.substring( 0, p );
      var value = cookie.substring( p + 1 );
      value = decodeURIComponent( value );
      cookies[ name ] = value;
    }
    return cookies;
  }());

彼がここで何をしたかがわかります。彼は関数を作成し、すぐに呼び出しました。この場合、なぜ彼がそんなことをするのか理解できません。「$」演算子を隠すために jQuery でこの慣用句が使用されているのを見たことがありますが、ここでは何も隠していません。彼が作成する唯一の変数は「cookies」であり、それが彼が入力している変数です。これが次のものとどのように違うのかわかりません:

var cookies = {};
var all = document.cookie;
if ( all !== "" )
{
    var list = all.split("; ");
    for ( var i = 0; i < list.length; i++ )
    {
      var cookie = list[ i ];
      var p = cookie.indexOf( "=" );
      var name = cookie.substring( 0, p );
      var value = cookie.substring( p + 1 );
      value = decodeURIComponent( value );
      cookies[ name ] = value;
    }
}

グローバルスコープの「すべて」の導入以外は?私が気付いていないこの特定の例で、彼が回避しているいくつかのより深いコーナーケースはありますか?

4

2 に答える 2

2

Javascriptには、グローバルと関数の2つのスコープしかありません。多くの言語とは異なり、ブロックスコープはありません。

したがって、代替コードは、、、、、、、をalllisti定義されているスコープに配置します。cookiepnamevaluecookies

これで、スニペットが関数定義内にあり、Cookieが返される場合、それはそれほど悪くないかもしれません。しかし、それがトップレベルのスクリプト内にある場合は、グローバル名前空間にダンプしている非常に一般的な変数名をたくさん見ています。

したがって、即時関数は、関数のスコープ制限が必要な場合に役立ちますが、後でFunctionオブジェクトを起動させたくはありません。

編集

他の利点を拡張するため。

即時関数のもう1つの一般的な使用法は、多くの場合、ブラウザーのスニッフィングが含まれる場合に、時間どおりにセットアップを行うことです。

var foo = (function(browser) {

    if(isBar(browser) {
        return function() {
            /* Some implementation of foo that is compatible with bar */
        };
    } else if(isBaz(browser) {
        return function() {
            /* Some implementation of foo that is compatible with baz */
        };
    } else {
        return function() {
            /* Some generic implementation of foo  */
        };
    }
}(browser_reference));

fooワンショットで、ブラウザが何であるかを決定するために必要な変数でスコープを乱雑にすることなく、のブラウザ互換バージョンを定義しました。

于 2012-09-04T21:21:25.490 に答える
0

Javascriptには名前空間の概念がありません。しかし、それはスコープの概念を持っています。サンプルコードは、コードをカプセル化し、名前空間をエミュレートする方法です。

基本的に、それはあなたのコードが他人のコードを誤って上書きすることを防ぎます(逆もまた同様です)。

于 2012-09-04T21:22:35.503 に答える