2016-04-23 17 views
1

Ich schaute auf viele Beiträge rund um globale/lokale Variablen, aber ich denke, ich vermisse etwas. Das ist, was ich versuche zu erreichen:Einstellung Javascript Variable innerhalb für Schleife

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

Statt der Definition meiner Liste der Befehle, würde Ich mag sie von einem Ajax-Aufruf dynamisch definieren. Dies ist mein bester Versuch:

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); 
      }); 
     } 
    }); 
} 

Das Hauptproblem besteht darin, dass in meiner Schleife, meine action Variable nicht durch a oder b in service ersetzt bekommen, die ich nehme an, weil action nur definiert wird, wenn die Funktion wird genannt. Die console.log kehrt:

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

Statt:

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

ich denke, u müssen hinzufügen "var" vor JSONdata = $ .parseJSON (Daten) – Fantasim

+0

Wo ist 'channel' definiert? – guest271314

+0

@ guest271314 Entschuldigung, es war ein Tippfehler, behoben. – Bnjii

Antwort

1

Zu allererst immer Ihre Variablen mit dem var Schlüsselwort deklarieren. Wenn nicht, werden sie im globalen Umfang erstellt und verschmutzen sie. Was noch wichtiger ist: Wenn Sie dies nicht tun, bricht Ihr Code, wie ich später erklären werde. Ich werde von jetzt an davon ausgehen, dass sie korrekt mit var deklariert sind.

Beginnen wir mit dem Ersetzen von socket.emit({action: [action]}); durch socket.emit({action: action});. Ihr Code verhält sich korrekt, d. H. Wenn Sie service[Object.keys(service)[0]] aufrufen, wird der Socket {action: 'a'} ausgeben. Sie erhalten jedoch nicht die Ausgabe, die Sie vom Konsolenprotokoll erwarten. Das Konsolenprotokoll zeigt:

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

, weil das ist, wie Sie die Funktion definiert, du hast definierst sie nicht mit dem Stringliteral „a“. Aber das ist überhaupt kein Problem, da die Aktion zur Laufzeit durch "a" ersetzt wird. In JavaScript werden Funktionen mit einem Verweis auf den Bereich erstellt, in dem sie erstellt wurden. Dies bedeutet, dass sie auf jede Variable dieses Bereichs zugreifen können, auch wenn sie außerhalb dieses Bereichs aufgerufen werden. Gute Erklärung hier http://javascript.info/tutorial/closures.

Also, um es zusammenzufassen, Ihre command_a Funktion einen Verweis auf action halten, wenn sein Wert „a“ und Ihre command_b Funktion einen Verweis auf action halten, wenn sein Wert „b“ ist, wenn und nur wenn Sie erklärt var action !!!!

Beachten Sie, dass wenn Sie action mit var action nicht deklarieren, wird es im globalen Bereich sein, und es wird den letzten Wert (d. H. "A") nach dem Ausführen Ihres Codes halten. Wenn entweder command_a() oder command_b() aufgerufen werden, geben beide {action: 'a'} aus, da action im globalen Gültigkeitsbereich liegt.

Eine letzte Sache, ursprünglich wollten Sie commandList ein Objekt sein, aber der Code, den Sie verwenden, erstellt ein Array. Dies würde Ihnen ein Objekt wie eingangs erwähnt:

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

Danke! Ihre Antwort und der von Ihnen eingegebene Link waren unglaublich hilfreich, um bessere Bereiche und Variablen in Fällen wie meiner besser zu verstehen. – Bnjii

1

Dies sollte die Syntax sein

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

1

Versuchen Klammern umgibt action bei socket.emit({action: action}); entfernen. Außerdem befindet sich console.log(service[Object.keys(service)[0]]); außerhalb des Funktionskörpers bei [command]:function(){}, wodurch ein Syntaxfehler entsteht. verschoben nach nach service Definition.

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

Perfekt, danke! – Bnjii

Verwandte Themen