一个棘手的JavaScript问题

时间:2009-06-27 17:27:57

标签: javascript serialization functional-programming scope

我最好通过代码解释一下。我有这样的事情:

var object1 = function(){ 
  //do something 
}
var object2 = function(){
  //do something else
}

var objects = {
  'o1' : object1,
  'o2' : object2  
};

var actions = [];

function addAction( actionName ){
 var object = objects[actionName];
 actions.push( function(){ new object(); } );
}

因此,此代码根据保存在数组中的用户输入保存一系列运行时确定的操作。

addAction( "o1" );
addAction( "o2" );

如果我想重播那个序列我就是这样做的:

for( i in actions ){
  actions[i]();
}

这将创建两个类型为object1和object2的匿名对象。

现在,我需要以某种方式序列化actions []数组,但我需要其中的每个函数来保留它的范围。如果我只是将函数转换为字符串,我得到:

"function(){ new object(); }"

如果我评估这个字符串,那么'object'将是未定义的。你会怎么做?

3 个答案:

答案 0 :(得分:5)

为什么不将动作的名称与对象中的函数一起保留,以便您可以将其用于序列化:

function Action(name, func) {
   this.name = name;
   this.func = objects[name];
}

function addAction(actionName) {
   actions.push(new Action(actionName));
}

运行函数的代码会略有改变:

for (i in actions) actions[i].func();

要序列化数组,您只需将名称放在字符串中:

var s = '';
for (i in actions) {
   s += (s.length == 0 ? '' : ',') + actions[i].name;
}

然后要反序列化,只需从名称中重新创建对象:

var names = s.split(',');
for (i in names) {
   addAction(new Action(names[i]));
}

答案 1 :(得分:2)

如果要序列化操作列表以便稍后播放,则应修改addAction函数以仅存储操作的名称。

function addAction(actionName)
{
    actions.push(actionName);
}

当你去回放时,你会使用

for(i in actions)
{
    objects[actions[i]]();
}

由于您的操作列表只是字符串,因此序列化应该没有问题。

答案 2 :(得分:1)

我对你期望该功能的范围有点不清楚。

只需按下

中的功能即可
actions.push(objects[actionName]);

可能会产生你想要的效果......

相关问题