JavaScript< - > DOM循环引用在现代浏览器中是否安全?

时间:2013-01-29 17:42:24

标签: javascript dom garbage-collection

我正在构建一个AJAX应用程序,它大量使用显示数据的表。为了简化设计,能够将表行(DOM)绑定到数据对象(JavaScript)并且反之亦然。因此,例如,如果单击一行,我知道哪个数据对象与该行一起使用,或者如果删除了数据对象,我很容易知道要从表中删除哪一行。几年前,当我尝试这个时,我最终导致了大量的内存泄漏。据我所知,IE8 +解决了大部分问题。现代版Chrome,FireFox和Safari怎么样?

这是代码的一个例子,这几天这是“安全的”吗?

// Email class, holds info about each email displayed in a table
function Email()
{
   this.To = "";
   this.From = "";
   this.Row = null;
}

// This array would actually come from an AJAX web service call
var Emails = new Array();
Emails[0] = new Email();
Emails[0].To = "whatever";
Emails[0].From = "hello";
Emails[1] = new Email();
Emails[1].To = "whatever";
Emails[1].From = "hello";

// Code like this would be used to build initial table, after this rows would
//  be added deleted as updates arrive via AJAX calls    
var table = document.createElement("table");
for(var x=0;x<Emails.length();x++)
{
   var row = table.insertRow(-1);
   row.Email = Emails[x]; // Is this safe?
   Emails[x].Row = row; // ...and also this?
   var cell = row.insertCell(-1);
   cell.innerHTML = Emails[x].To;
   cell = row.insertCell(-1);
   cell.innerHTML = Emails[x].From;
}

1 个答案:

答案 0 :(得分:2)

这是安全的,因为在你的javascript和DOM元素超出范围(你的页面消失,javascript对象超出范围)之后的某个时候,内存最终会被清除。

但是,我建议不要这样做。您基本上是在代码中创建表,然后将这些DOM元素与业务对象相关联。这是混合用户界面和逻辑。

我建议使用KnockoutJS让它为你处理所有DOM-to-JavaScript绑定。使用KnockoutJS,我会编写如下代码:

HTML:

<table>
   <tbody data-bind="foreach: Emails">
      <tr>
        <td data-bind="html: To"></td>
        <td data-bind="html: From"></td>
      <tr>
   </tbody>
</table>

JavaScript的:

var viewModel = {
   Emails: ko.observableArray()
};

makeSome.AjaxCall(function(emailResults) {
    viewModel.Emails(emailResults);
}

ko.applyBindigns(viewModel);

现在你的UI停留在DOM中,你的逻辑保留在JavaScript中。

作为额外的奖励,每当您向viewModel.Emails数组添加或删除电子邮件时,DOM都会更新。例如,仅调用 viewModel.Emails.remove(someEmail)将自动为您更新DOM;同上.push。