javascript 我知道在 DOM 中存储数据不好,但为什么呢?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5905994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 18:45:33  来源:igfitidea点击:

I know its bad to store data in the DOM, but why?

javascriptjquerydom

提问by Jordan Sitkin

I've heard over and over again that it is bad practice to "use the DOM as a database."

我一遍又一遍地听说“将 DOM 用作数据库”是不好的做法。

While I mostly agree with that sentiment, this question is more about the less black and white cases. Keeping in mind the latest revisions to jQuery's .data()methods and the HTML5 data-attribute spec, is it really so bad to stick some data in the DOM for the sake of convenience?

虽然我基本同意这种观点,但这个问题更多地是关于非黑即白的案例。记住 jQuery 的.data()方法和 HTML5 数据属性规范的最新修订版,为了方便而将一些数据粘贴在 DOM 中真的很糟糕吗?

For example, I recently implemented a "live" calculation feature on a table full of inputs by doing something like this:

例如,我最近通过执行以下操作在充满输入的表上实现了“实时”计算功能:

<table>
  <tr>
    <td><input type="text"></td>
  </tr>
  <tr>
    <td><input type="text"></td>
  </tr>
</table>

jQuery:

jQuery:

$('table').bind('calculate',function(){
  var total = 0;
  $(this).find('tr').each(function(){
    total += $(this).data('value');
  });
  // display total
});

$('table input').bind('change keyup',function(){
  $(this).closest('tr').data('value',$(this).val());
  $(this).closest('table').trigger('calculate');
});

This is an over-simplified example because I couldskip the calls to .data()and go straight to the input values, but let's imagine a slightly more complex scenario where elements other than inputs are affecting the row values.

这是一个过于简化的示例,因为我可以跳过对.data()输入值的调用并直接转到输入值,但让我们想象一个稍微复杂一些的场景,其中输入以外的元素正在影响行值。

Is it wrong to use the DOM to store simple data in this kind of situation?

在这种情况下使用 DOM 存储简单数据是错误的吗?

回答by Anurag

It's fine to store data in DOM objects. And since your question is specific to jQuery's data API, it's important to understand how the dataAPI works. I wrote an answerexplaining its inner workings a while back. The data API only keeps a reference to the DOM objects along with the data, and doesn't store anything inside the DOM objects themselves. All data is stored in plain old JavaScript objects.

将数据存储在 DOM 对象中是可以的。由于您的问题特定于 jQuery 的数据 API,因此了解dataAPI 的工作原理很重要。不久前,我写了一个答案,解释了它的内部工作原理。数据 API 只保留对 DOM 对象的引用以及数据,并且不会在 DOM 对象本身中存储任何内容。所有数据都存储在普通的旧 JavaScript 对象中。

The issue of whether that is a good or a bad approach is a matter of personal taste. John Resig, the creator of jQuery, gave a talk at Tech4Africa in 2010 where he talks about this exact issue, and proposes to do away with a separate storage area and link everything with the DOM using the data API. You can see the talk on YouTube(thanks to @tine2k for providing the link). If you listen to the entire talk, you'll find some good examples of why this approach makes sense and keeps things simple.

这是一个好方法还是一个坏方法的问题是个人品味的问题。jQuery 的创建者 John Resig 于 2010 年在 Tech4Africa 上发表演讲,他谈到了这个确切的问题,并建议取消单独的存储区域,并使用数据 API 将所有内容与 DOM 链接。你可以在YouTube 上看到这个演讲(感谢@tine2k 提供链接)。如果你听完整个演讲,你会发现一些很好的例子来说明为什么这种方法有意义并且让事情变得简单。

I believe similar arguments can be made for the other end of the spectrum - to have your data in neatly tucked away objects, and classes, and be separate from the view itself. That sort of thinking comes from traditional architectures such as MVC.

我相信可以为频谱的另一端提出类似的论点 - 将您的数据整齐地隐藏在对象和类中,并与视图本身分开。这种想法来自于传统的架构,比如 MVC。

I say it's fine to go with either approach - using the DOM to store data, or using a classical approach. Just don't mix the two, cause then you application model is sprinkled everywhere.

我说这两种方法都可以——使用 DOM 存储数据,或者使用经典方法。只是不要将两者混用,因为那样您的应用程序模型就会到处都是。

回答by RobG

There are some fundamental arguments against using the DOM to store data:

有一些反对使用 DOM 存储数据的基本论点:

  1. The DOM is supposed to be a view of data. The properties of DOM elements should be metadata for the elements themselves, not data from the model.

  2. You should not add random properties to host objects as you have no idea what they might do with them.

  3. You have the same issue as global variables - if it becomes common practice, you will have to adopt a scheme to avoid name collisions.

  1. DOM 应该是数据视图。DOM 元素的属性应该是元素本身的元数据,而不是来自模型的数据。

  2. 您不应该向宿主对象添加随机属性,因为您不知道它们可以用它们做什么。

  3. 您有与全局变量相同的问题 - 如果它成为普遍做法,您将不得不采用一种方案来避免名称冲突。

There is also the argument that the DOM is a pretty ordinary data store and that object structure with indexes will be much more efficient for anything other than trivial data needs.

还有一种观点认为 DOM 是一个非常普通的数据存储,并且带有索引的对象结构对于除微不足道的数据需求之外的任何事情都会更有效。

If you only have small amounts of data and have full control over your pages, then go ahead and put data in data- attributes and properties. But do not store large chunks or complex structures.

如果您只有少量数据并且可以完全控制您的页面,那么继续将数据放入数据属性和属性中。但不要存储大块或复杂的结构。

Oh, and I don't think there are any performance issues - accessing an element and its properties in the DOM is likely no faster or slower than accessing some part of an object structure, though I'm sure there are faster and slower ways of doing both.

哦,我不认为有任何性能问题 - 访问 DOM 中的元素及其属性可能不会比访问对象结构的某些部分更快或更慢,尽管我确信有越来越快的方法两者都做。

回答by Chad

I don't think there is anything wrongwith storing data in the DOM, but I think the issue lies with storing a lotof data in the DOM. The browser does have to muddle through the DOM to output the pages we see, and the more data that is in there the more crap it has to sort out.

我不认为在 DOM 中存储数据有什么问题,但我认为问题在于在 DOM 中存储了大量数据。浏览器确实必须通过 DOM 来输出我们看到的页面,而且那里的数据越多,它需要整理的废话就越多。

I'm sure there are also other reasons as well, this is just my deduction.

我相信还有其他原因,这只是我的推论。

回答by Drew Deal

Having developed a few single page apps for CE devices that have limited browser power, I have adopted a few extra personal standards about these things. The main thing is that just because JQuery supports scanning through the DOM, that does not suggest it as a performant approach. If I need to know which LI has focus, I could use .index() or .find() or even .each(), but keeping that value in a separate model object is better for the following reasons:

在为浏览器功能有限的 CE 设备开发了一些单页应用程序后,我对这些事情采用了一些额外的个人标准。主要的是,仅仅因为 JQuery 支持扫描 DOM,并不建议将其作为一种高性能方法。如果我需要知道哪个 LI 具有焦点,我可以使用 .index() 或 .find() 甚至 .each(),但由于以下原因,将该值保留在单独的模型对象中更好:

  1. MVC is a real thing, despite the rampant abuse through doing things like using the DOM as a state holder. Keeping state in the model as a rule makes MVC make sense.
  2. Scanning through the LI tags is more expensive than using listItems.focussed in code.
  3. The DOM is busy being manipulated and your queries on it may be delayed or cause delays.
  1. MVC 是一个真实的东西,尽管通过使用 DOM 作为状态持有者之类的事情来滥用猖獗。在模型中保持状态作为一项规则使 MVC 有意义。
  2. 扫描 LI 标签比在代码中使用 listItems.focussed 更昂贵。
  3. DOM 正忙于操作,您对它的查询可能会延迟或导致延迟。
根据马特@ https://github.com/Matt-Esch/virtual-domhttps://github.com/Matt-Esch/virtual-dom,“读取某些 DOM 节点属性甚至会导致副作用。” 我倾向于同意这一点,但我承认我正在寻找关于这一点的更多证据,因为被任命追查我们最大的应用程序性能问题的人我个人认为这些问题主要与 DOM 相关代码有关。