Хитрый вопрос о JavaScript - PullRequest
1 голос
/ 27 июня 2009

Я, наверное, лучше объясню это через код. Я получил что-то вроде этого:

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

и если я вычислю эту строку, то 'объект' будет неопределенным. Как бы вы это сделали?

Ответы [ 3 ]

5 голосов
/ 27 июня 2009

Почему бы не сохранить имя действия вместе с функцией в объекте, чтобы ее можно было использовать для сериализации:

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]));
}
2 голосов
/ 27 июня 2009

Если вы хотите сериализовать свой список действий для последующего воспроизведения, вам следует изменить функцию addAction, чтобы просто сохранить имя действия.

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

А когда вы начнете воспроизведение, вы будете использовать

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

Поскольку ваш список действий - просто строки, у вас не должно быть проблем с сериализацией.

1 голос
/ 27 июня 2009

Мне немного непонятно, какую область вы ожидаете иметь для этой функции.

Просто нажмите на функцию в

actions.push(objects[actionName]);

может иметь желаемый эффект ...

...