在for循环中设置Javascript变量

时间:2016-04-23 16:12:43

标签: javascript jquery

我查看了很多关于全局/局部变量的帖子,但我想我错过了一些东西。 这就是我想要达到的目的:

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变量不会被a中的bservice取代,我认为这是因为{{ 1}}仅在调用函数时定义。 action返回:

console.log

而不是:

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

3 个答案:

答案 0 :(得分:1)

这应该是语法

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

答案 1 :(得分:1)

尝试删除actionsocket.emit({action: action});周围的括号。此外,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

答案 2 :(得分: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

因此,总结一下,当command_a函数的值为" a"时,action函数将保留对command_b的引用。当action函数的值为" b"时,var action函数将保留对action的引用,当且仅当您声明var action !!!!

请注意,如果您未使用command_a()声明command_b(),则它将在全局范围内,并且它将保留最后一个值(即" a" )代码执行后。调用{action: 'a'}action时,它们都会发出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}); }; }); } }); 位于全局范围内。

最后一件事,你最初希望KeyedMessage(twitter-test_english,null,null,{"created_at":"Sat Apr 23 18:31:10 +0000 2016","id":723942306777337856,"id_str":"723942306777337856"} 成为一个对象,但你使用的代码会创建一个数组。这会给你一个最初陈述的对象:

{"created_at":"Sat Apr 23 18:31:10 +0000 2016","id":723942306777337856,"id_str":"723942306777337856"}

message = new KeyedMessage("twitter-test_english", (String)queue.take());
//System.out.println("This is message"+message.message());
String message_string = message.message().toString();
JsonParse.toParseJson(message_string);

}