一个棘手的JavaScript问题

dis*_*cer 1 javascript serialization scope functional-programming

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

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(); } );
}
Run Code Online (Sandbox Code Playgroud)

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

addAction( "o1" );
addAction( "o2" );
Run Code Online (Sandbox Code Playgroud)

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

for( i in actions ){
  actions[i]();
}
Run Code Online (Sandbox Code Playgroud)

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

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

"function(){ new object(); }"
Run Code Online (Sandbox Code Playgroud)

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

Guf*_*ffa 5

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

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

function addAction(actionName) {
   actions.push(new Action(actionName));
}
Run Code Online (Sandbox Code Playgroud)

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

for (i in actions) actions[i].func();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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