Javascript hasChildNodes vs firstChild
比较上面的两段伪代码,它们都将Javascript hasChildNodes vs firstChild,javascript,dom,dom4,Javascript,Dom,Dom4,比较上面的两段伪代码,它们都将div的每个子级追加到fragment中,直到不再有子级为止 您什么时候会喜欢hasChildNodes或firstChild它们看起来是一样的 如果API如此相似,那么为什么它们都存在呢。当我可以将firstChild从null强制为false a) 微优化 b) 虽然这似乎是常见的做法,但我不喜欢依赖null/non-null值来替代false/true。在启用服务器压缩的情况下,这是一种不必要的节省空间的方法(有时可能会调用细微的bug)。每次都要选择清晰,除
div
的每个子级追加到fragment
中,直到不再有子级为止
hasChildNodes
或firstChild
它们看起来是一样的firstChild
从null
强制为false
我会选择第一个选项,因为它完美地解释了您的意图。由于返回的
原因,我建议您选择它hasChildNodes()
如果为空则返回false
,而firstChild
返回null
;这使您在检查数据是否存在时能够更有效地解析数据。实际上,这取决于您计划如何操作DOM来实现您的结果。这两种实现之间没有功能上的差异。两者在所有情况下都会产生相同的结果
如果您想了解两者之间是否存在性能差异,则必须在所需的目标浏览器上运行性能测试,以查看是否存在有意义的差异
这是两个例子中的一个。它似乎是特定于浏览器的,哪一个更快hasChildNodes()
在Chrome中的速度要快得多,但在IE9和Firefox中,firstChild
的速度要快一点
除了一些(可能)可以忽略的速度差异外,您的两个示例通常*表现相同
选择其中一个而不是另一个的唯一原因是清晰性,特别是每个构造在多大程度上代表了代码其余部分正在实现的思想,这取决于在阅读代码时,其中一个构造是否更容易直观地解析。我建议尽可能地倾向于清晰而不是性能,或者不必要的迂腐的正确性
*注意:我假设您正在一个模糊的现代浏览器中的网页上运行此代码。如果您的代码需要在其他上下文中运行,.hasChildNodes()和.firstChild()之间可能存在显著的速度差异,甚至功能(副作用)差异:需要设置和执行函数调用,另一种方法是,如果第一个子对象的表示形式不可用,则需要构造一个与脚本兼容的DOM表示形式。假设DOM调用速度较慢,您可以通过使用对第一个子对象的单个调用来进一步优化(以牺牲可读性为代价):
while (div.hasChildNodes()) {
fragment.appendChild(div.firstChild)
}
while (div.firstChild) {
fragment.appendChild(div.firstChild)
}
。。。尽管(奇怪的是,对我来说)这显然没有任何帮助,而且让事情变得更糟,根据这个jsPerf:
至于这两种方法存在的原因,请记住DOM不是JavaScript独有的。例如,在Java DOM实现中,您必须显式地将firstChild
(或者更可能的是firstChild()
)与null
进行比较,但是div.firstChild
不会更快,因为它是一个静态值,而不是div.hasChildNodes()
,哪个是要调用的查找函数?@ElliotBonneville它完全取决于实现。强制div.firstChild
为boolean可能比函数调用开销快,但如果不进行测量,就无法确切地知道。@Elliot:仅仅因为它不是函数,并不能消除导致复杂代码响应读/写而运行的可能性。考虑DOM元素的内层HTML属性。这会导致一些主要的活动,不是吗?我想说而(var fc=div.firstChild)片段。appendChild(fc)
会让另一个更快。哈!你的伪代码不会永远循环吗?@Raynos,有许多api为用户提供了不同的方式来断言相同的信息,特别是如果这种语言有一点历史的话。
var child;
while ( (child = div.firstChild) ) {
fragment.appendChild(child);
}