문제

while (div.hasChildNodes()) {
    fragment.appendChild(div.firstChild)
}

while (div.firstChild) {
    fragment.appendChild(div.firstChild)
}

Comparing the two pieces of pseudo code above, they both append each child of div to fragment until there are no more children.

  1. When would you favour hasChildNodes or firstChild they seem identical.
  2. If the APIs are so similar then why do they both exist. Why does hasChildNodes() exist when I can just coerce firstChild from null to false
도움이 되었습니까?

해결책

a) micro-optimization!

b) Although it seems to be common practice, I'm not fond of relying on null/non-null values being used as a substitute for false/true. It's a space saver that's unnecessary with server compression enabled (and can sometimes call subtle bugs). Opt for clarity every time, unless it's demonstrated to be causing bottlenecks.

I'd go for the first option, because it explains your intent perfectly.

다른 팁

There's no functional difference between your two implementations. Both generate the same results in all circumstances.

If you wanted to pursue whether there was a performance difference between the two, you would have to run performance tests on the desired target browsers to see if there was a meaningful difference.

Here's a performance test of the two. It appears to be browser-specific for which one is faster. hasChildNodes() is significantly faster in Chrome, but firstChild is a little bit faster in IE9 and Firefox.

enter image description here

I would suggest hasChildNodes() over firstChild just due to the return; hasChildNodes() returns false if it's blank, while firstChild returns null; which allows you to parse the data more efficiently when it comes to checking if they exist. Really, it depends on how you plan on manipulating the DOM to achieve your results.

Your two examples will usually* behave identically, aside from some (probably) negligible differences in speed.

The only reason to favor one over the other would be clarity, specifically how well each construct represents the ideas the rest of your code is implementing, modulated by whether one of them is easier for you to visually parse when you're reading the code. I suggest favoring clarity over performance or unnecessarily pedantic correctness whenever possible.

* Note: I'm assuming you're running this code on a webpage in a vaguely modern browser. If your code needs to run in other contexts, there might be a significant speed difference or even functional (side-effect) differences between .hasChildNodes() and .firstChild: One requires a function call to be set up and executed, the other requires that a script-ready DOM compliant representation of the first child be constructed if it isn't already available.

Assuming DOM calls are slow, you could optimize further (at the expense of readability) by using a single call to firstChild:

var child;
while ( (child = div.firstChild) ) {
    fragment.appendChild(child);
}

... although (bizarrely, to me) this apparently doesn't help at all and makes things worse, according to this jsPerf: http://jsperf.com/haschildnodes-vs-firstchild/2

As to why both methods exist, remember that DOM is not exclusive to JavaScript. In a Java DOM implementation, for example, you would have to explicitly compare firstChild (or more likely firstChild()) to null.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top