2010-06-12 20 views
5

Estoy trabajando en una plataforma de migración para migrar aplicaciones web de un dispositivo a otro. Lo extiendo para agregar el soporte para preservar el estado de JavaScript. Mi tarea principal es crear un archivo que represente el estado actual de la aplicación en ejecución, transmitirlo a otro dispositivo y volver a cargar el estado en el dispositivo de destino.¿Cómo conservar el estado del cierre de JavaScript?

La solución básica adopté es navegar por el objeto de la ventana y para guardar todas sus propiedades descendientes usando JSON como formato de base para la exportación, y se amplía para implementar algunas de las características:

  • preservando referencia de objeto, incluso si cíclica (dojox.json.ref biblioteca)
  • soporte para temporizadores
  • Fecha
  • no numericproperties de arrays
  • referencia a DOM elementos

La tarea más importante de que necesito resolver ahora es la exportación de cierres. En este momento, no sabía cómo implementar esta función. Leí sobre la propiedad interna EcmaScript [[scope]] que contiene la cadena de alcance de una función, un objeto similar a una lista compuesto por todo el contexto de activación anidado de la función. Desafortunadamente, no es accesible por JavaScript. ¿Alguien sabe si hay una manera de acceder directamente a la propiedad [[scope]]? ¿O otra forma de preservar el estado de un cierre?

+1

No, no hay una forma estándar de acceder al '[[Ámbito]]' actual, la única implementación que proporciona una forma para esto es Rhino, a través de su propiedad '__parent__', p. 'var scope = function() {} .__ parent __;' – CMS

+0

¿La propiedad '__parent__' de Rhino es la misma proporcionada por Firebug? –

Respuesta

2

Esto suena como una hazaña imposible, ya que necesitaría acceder a las referencias almacenadas en cada variable.

La mejor solución sería, probablemente, primero refactorizar su código para almacenar el estado en un objeto disponible, de esa manera podría usar fácilmente JSON.stringify/parse para guardarlo/restaurarlo.

Así que van desde

var myFuncWithScope = (function() { 
    var variable = 0; 
    return function() { 
     return variable++; 
    } 
})(); 

var serializedState = .... // no can do 

a

var state = { 
    myScope = { 
     variable: 0 
    } 
}; 

var myFuncWithoutScope = function(){ 
    return state.myScope.variable++; 
} 

var serializedState = JSON.stringify(state); 
+0

No está claro a qué te refieres con "refactorizar tu código para almacenar estado en un objeto disponible", pero creo que es lo que realmente estoy haciendo cuando almaceno todas las propiedades de 'ventana' en un mapa y paso ese mapa a mi versión modificada de JSON. Lo que estaba preguntando en esta publicación era una solución al problema: "¿Cómo puedo serializar un cierre y restaurarlo en otro dispositivo?" –

+0

Mi punto era que no se puede serializar/deserializar un alcance. Pero si todo el estado se almacena * fuera * del cierre, como propiedades, entonces no es necesario almacenar el cierre, ya que puede ser recreado por script. –

+0

Solución muy interesante, pero creo que no es aplicable a mi caso y, en cualquier caso, la refactorización de código va más allá del alcance de mi trabajo. –

2

Desde donde estás ejecutando? Si es una aplicación nativa o una extensión de navegador web, puede tener alguna esperanza, a través del acceso interno a cualquier motor de scripting que esté usando. Pero a partir de un script en contenido web, no hay esperanza.

[[Scope]] es una propiedad interna de ECMAScript a la que no se puede acceder o conservar desde dentro del intérprete, pero lejos del único; casi todas las propiedades [[...]] no son accesibles. Referencias de código de función, prototipos, propiedades, enumeración, contexto de propietario, oyentes, todo lo relacionado con objetos de host (como nodos DOM) ... hay infinitas maneras de fallar.

No puede conservar o migrar aplicaciones web sin que se les exija seguir reglas estrictas para evitar todas las funciones de JS, excepto las más básicas.

+0

La plataforma tiene un proxy de migración entre el servidor y el cliente, que intercepta las solicitudes de la página del cliente y responde con una página web modificada con algunos JavaScript. Así que estoy ejecutando desde un script en contenido web. Sé que sería difícil migrar completamente el estado de JavaScript, pero estoy tratando de resolver los subproblemas uno por uno. Quería usar JavaScript puro porque quería que la plataforma de migración funcionara con todos los navegadores. Pero, si es necesario, podría usar algún código dependiente del navegador. p. Me preguntaba cómo guarda FireBug pistas de las cadenas de alcance en el seguimiento de pila ... –

+0

Firebug es una extensión de navegador, por lo que tiene acceso al estado de intérprete interno que no podrá ver desde el contenido web. No es solo difícil migrar completamente el estado, es explícitamente imposible. Hay algunos objetos que tienen un estado externo, por lo que simplemente no se pueden clonar/serializar/restaurar incluso con acceso de nivel nativo, sin importar el acceso limitado que se obtiene del contenido web. – bobince

Cuestiones relacionadas