如何安全地跨窗口传输对象的引用?

时间:2010-06-07 08:37:01

标签: javascript garbage-collection

我正在调试一个Web应用程序。 Javasript在一个窗口中创建一个对象并将其用作参数以在另一个窗口中调用全局方法。伪代码如下所示。

var obj = new Foo();
anotherWin.bar(obj);

anotherWin 中,参数存储在全局变量中。

var g_obj;

function bar(obj)
{
   g_obj = obj;
   ...
}

当其他函数尝试引用 g_obj.Id 时,它会抛出异常“无法计算表达式”。这种情况发生在Windows 7的IE8.0.7600.16385中。

在Visual Studio调试器中,发生此异常时, g_obj 显示为

 {...}

看起来它的所有属性都丢失了。

也许根本原因是对象是在一个窗口中创建的,但只在另一个窗口中引用。该对象可能随时被垃圾收集。

有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:4)

DOM对象不会跨窗口持久存在。但是,如果您可以使用JSON representation,那么我将您的对象转换为JSON ,将其发送,然后解析JSON。

有几种方法可以在javascript中编码和解码JSON (提示:使用eval()是安全灾难)。

  • 一些现代浏览器(Firefox> = 3.5,Internet Explorer> = 8.0)提供安全,快速的原生实现。
  • 来自相同功能的一些javascript框架(例如YUInot jquery)。
  • 执行此操作的 reliable way 使用道格拉斯·克罗克福德的json2.js library 它符合标准,安全,向后兼容并将使用浏览器本机解析器(如果存在)。

使用Crockford的库,您的示例将成为:

<script type="text/javascript" src="json2.js"></script>

[...]

var obj = new Foo();
anotherWin.json_bar(JSON.stringify(obj));

anotherWin

<script type="text/javascript" src="json2.js"></script>

[...]

var g_obj;

function bar(obj)
{
   g_obj = obj;
   [...]
}


function json_bar(json_obj)
{
    bar(JSON.parse(json_obj));
}

不要忘记minify json2.js - 在保守缩小的情况下,您的页面加载大小仅为3.5KB。

答案 1 :(得分:1)

这是一个单向操作,还是希望在anotherWin中进行的更改能够反映在源窗口中?

如果它是单向的,我会将它转换为json字符串,将其发送出去,并将其解析回一个对象。

传递参考可能不可行。

答案 2 :(得分:1)

序列化您的对象,将其发送,然后反序列化。