2016-04-23 19 views
1

グローバル/ローカル変数の周りにたくさんの投稿を見ましたが、何か不足していると思います。forループ内でJavascript変数を設定する

var commandList = { 
    'command_a': function() { 
     socket.emit({action: 'a'}); 
    }, 
    'command_b': function() { 
     socket.emit({action: 'b'}); 
    } 
}; 

代わりのコマンドの私のリストを定義し、私はAJAX呼び出しから動的にそれらを定義したいと思います: これは私が取得しようとしているものです。 これが私の最高の試みです:

function getCommands() { 
    $.ajax({ 
     type:'get', 
     url: '/getCommands', 
     data: data,  
     success: function(data) { 

      JSONdata = $.parseJSON(data); 
     // [{"action": "b", "command": "command_b"},{"action": "a", "command": "command_a"}] 

      var commandList = []; 

      jQuery.each(JSONdata, function(i, val) { 

       command = val['command']; 
       action = val['action']; 

       service = { 
        [command]: function() { 
         socket.emit({action: [action]}); 
        } 
       console.log(service[Object.keys(service)[0]]); 
       } 
       commandList.push(service); 
      }); 
     } 
    }); 
} 

主な問題は、私のループでは、私のaction変数は、私はactionのみ定義されますので、あると仮定しaまたはbserviceで、置き換えられませんということであるときに、関数が呼び出されます。 console.logリターン:

function() { 
        socket.emit({action: [action]}); 
       } 

の代わりに:

function() { 
        socket.emit({action: 'a'}); 
       } 
+0

を私はuが 'channel'が定義されている – Fantasim

+0

JSONdata = $ .parseJSON(データ)の前に "VAR" を追加する必要があると思いますか? – guest271314

+0

@ guest271314申し訳ありませんがタイプミスで修正しました。 – Bnjii

答えて

1

まず、常にvarキーワードを使用して変数を宣言。そうしないと、グローバルスコープで作成され、それを汚染します。もっと重要なことは、そうしなければ、後で説明するように、コードが壊れることです。私は今からvarで正しく宣言されていると仮定します。

socket.emit({action: [action]});socket.emit({action: action});に置き換えてみましょう。コードが正しく動作します。つまり、service[Object.keys(service)[0]]に電話すると、ソケットは{action: 'a'}を発信します。ただし、コンソールログから期待する出力は得られません。コンソールログは示しています

function() { 
       socket.emit({action: action}); 
      } 

それはあなたが機能を定義した方法ですので、あなたは文字列リテラル「A」とそれを定義していませんでした。実行時にアクションが "a"に置き換えられるため、これはまったく問題ありません。 javascriptでは、関数は作成されたスコープへの参照で作成されます。つまり、スコープ外で呼び出された場合でも、そのスコープの変数にアクセスできます。良い説明はこちらhttp://javascript.info/tutorial/closures

その値が「B」である場合にのみ、あなたの場合ならば、その値は「」とあなたのcommand_b機能は、actionへの参照を保持しますされたときに、それをまとめるために、あなたのcommand_a機能はactionへの参照を保持します宣言したvar action !!!!

actionvar actionと宣言しないと、グローバルスコープになり、コード実行後に最後の値(つまり「a」)が保持されます。 command_a()またはcommand_b()のいずれかが呼び出されると、actionがグローバルスコープ内に存在するため、両方とも{action: 'a'}を発信します。

最後に、commandListをオブジェクトにしたいと思っていましたが、使用しているコードによって配列が作成されていました。最初に述べたようにこれは、あなたのオブジェクトを与える:

function getCommands() { 
$.ajax({ 
    type:'get', 
    url: '/getCommands', 
    data: data,  
    success: function(data) { 

     JSONdata = $.parseJSON(data); 
    // [{"action": "b", "command": "command_b"},{"action": "a", "command": "command_a"}] 

     var commandList = {}; 

     jQuery.each(JSONdata, function(i, val) { 
      var command = val['command']; 
      var action = val['action']; 

      commandList[command] = function() { 
        socket.emit({action: action}); 
      }; 
     }); 
    } 
}); 

}

+0

ありがとう!あなたの答えとあなたが含むリンクは、私のような場合にスコープや変数を理解するのに非常に役立ちました。 – Bnjii

1

これはsocket.emit({action: action});actionを囲む括弧を削除してください構文

service = {}; service[command] = function(){ var actionObj ={}; actionObj.action = action; socket.emit(actionObj); }

1

でなければなりません。また、console.log(service[Object.keys(service)[0]]);が機能体の外側にある[command]:function(){}にあり、構文エラーが発生します。 serviceの定義の後に移動しました。すべての

var commandList = []; 

jQuery.each(JSONdata, function(i, val) { 

    var command = val["command"]; 
    var action = val["action"]; 

    var service = { 
    [command]: function() { 
     socket.emit({action: action}); // removed brackets at value `action` 
    } 
    }; 
    console.log(service[Object.keys(service)[0]]); // moved outside of `service` 
    commandList.push(service); 
}); 

plnkr http://plnkr.co/edit/VkmPGl9lWwiPKarvrbLJ?p=preview

+0

パーフェクト、ありがとう! – Bnjii

関連する問題