如何保持JavaScript闭包的状态?

如何保持JavaScript闭包的状态?,javascript,json,closures,Javascript,Json,Closures,我正在开发一个迁移平台,将web应用程序从一个设备迁移到另一个设备。我正在扩展它以添加对保存JavaScript状态的支持。 我的主要任务是创建一个表示正在执行的应用程序的当前状态的文件,将其传输到另一个设备,并在目标设备中重新加载该状态 我采用的基本解决方案是导航窗口对象,并使用JSON作为导出的基本格式保存其所有子体属性,并对其进行扩展以实现一些功能: 保留对象引用,即使是循环的(dojox.json.ref库) 对计时器的支持 日期 数组的非数值性质 对DOM元素的引用 我现在需要解决

我正在开发一个迁移平台,将web应用程序从一个设备迁移到另一个设备。我正在扩展它以添加对保存JavaScript状态的支持。 我的主要任务是创建一个表示正在执行的应用程序的当前状态的文件,将其传输到另一个设备,并在目标设备中重新加载该状态

我采用的基本解决方案是导航窗口对象,并使用JSON作为导出的基本格式保存其所有子体属性,并对其进行扩展以实现一些功能:

  • 保留对象引用,即使是循环的(dojox.json.ref库)
  • 对计时器的支持
  • 日期
  • 数组的非数值性质
  • 对DOM元素的引用
我现在需要解决的最重要的任务是导出闭包。此时此刻,我不知道如何实现此功能。 我阅读了关于内部EcmaScript属性
[[scope]]
的内容,该属性包含函数的作用域链,一个由函数的所有嵌套激活上下文组成的类似列表的对象。不幸的是,JavaScript无法访问它。
有人知道是否有直接访问
[[scope]]
属性的方法吗?还是另一种保存闭包状态的方法?

这听起来像是不可能的壮举,因为您需要访问存储在每个变量中的引用

最好的解决方案可能是首先将代码重构为在可用对象上存储状态,这样您就可以轻松地使用JSON.stringify/parse来保存/恢复它

所以从

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

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


你从哪里执行?如果您是本地应用程序或web浏览器扩展,那么通过内部访问它所使用的脚本引擎,您可能会有一些希望。但从web内容中的脚本来看,没有希望

[[Scope]]
是一个ECMAScript内部属性,您无法从解释器内部访问或保留它,但它远远不是唯一的属性;几乎所有的
[…]
属性都不可访问。函数代码引用、原型、属性、可枚举性、所有者上下文、侦听器,以及与主机对象(如DOM节点)有关的一切。。。失败的方式有无数种


如果不要求web应用程序遵循一些严格的规则来避免最基本的JS功能,则无法保留或迁移web应用程序。

不,没有标准的方法来访问当前的
[[Scope]]
,Rhino是唯一一个通过其
\uuuuuuuuuuuu父属性实现此功能的实现,例如,
var scope=function(){}.\uuuu parent\uuuuu
Rhino的
\uuuuuu parent\uuuuuuu
属性是否与Firebug提供的属性相同?该平台在服务器和客户端之间有一个迁移代理,它拦截客户端页面请求,并使用带有一些JavaScript的修改过的网页进行响应。所以我是从web内容中的脚本执行的。我知道很难完全迁移JavaScript状态,但我正在尝试逐个解决子问题。我想使用纯JavaScript,因为我想让迁移平台与每个浏览器一起工作。但是,如果有必要,我可以使用一些依赖于浏览器的代码。e、 我想知道FireBug是如何在堆栈跟踪中跟踪作用域链的……FireBug是一个浏览器扩展,因此可以访问内部解释器状态,您将无法从web内容中看到。完全迁移状态不仅困难,而且显然是不可能的。有些对象具有外部状态,因此即使使用本机级别的访问也无法克隆/序列化/还原,更不用说您从web内容获得的有限访问。不清楚“将代码重构为在可用对象上存储状态”是什么意思但我认为,当我将所有
window
属性存储在一个映射中,并将该映射传递给我修改过的JSON版本时,这就是我实际正在做的事情。我在这篇文章中问的是一个问题的解决方案:“如何序列化一个闭包并将其恢复到另一个设备中?”我的观点是,您不能序列化/反序列化一个作用域。但是,如果所有状态都作为属性存储在闭包之外,那么您就不需要存储闭包,因为它可以通过脚本重新创建。这是一个非常有趣的解决方案,但我认为它不适用于我的情况,而且代码重构远远超出了我的工作范围。编辑:您得到了检查!:)事实上,在你提出这个想法几个月后,我采纳了你的想法。我用ANTLR创建了一个JS2JS编译器。我远不是一个通用的解决方案,但我成功地迁移了一些包含词法闭包的示例网站,例如。我想让你看看我的最后一个问题:。非常感谢。
var state = {
    myScope = {
        variable: 0
    }
};

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

var serializedState = JSON.stringify(state);