Consider this code snippet: var xml:XML = <outer><inner>null</inner></outer>; var xmlList:XMLList = xml.inner; trace(xmlList == null);
What does the trace statement output, true or false, and why? Well, first, let's stipulate that the "innner" element in the XML object contains the String "null". It's not an empty element, for those who might think that "null" is interpreted as a literal null. Second, the expression "xml.inner" returns a non-null XMLList object, which is assigned to the variable xmlList. If you were to dereference the xmlList variable, say by calling its "length()" method, it would assuredly not throw a #1009 null reference error, but rather it would return 1, which is the number of child elements of "outer" that have the name "inner". So the "inner" element is the only member of xmlList. So now you have reference to a non-null XMLList of length 1. It seems obvious that comparing that reference to null with the equality operator (==) should evaluate to false, right? Well, it doesn't. The expression: xmlList == null evaluates to true, and that is what the trace statement outputs in the original example. After spending about 4 hours looking in all the wrong places for a bug that was actually caused by this odd little quirk, once I found out what was really causing the problem, I thought for sure that it had to be a bug in the ActionScript or E4X implementation. After all, it can't be right that a non-null object reference is considered equivalent to null, right? Wrong again. If you read the ASDoc for the equality operator, that's what it's supposed to do. In the Flex 3.2 Language Reference, the section on the equality operator says: "If the data types of the operands do not match, the result is false except in the following circumstances: ... One operand is of type XMLList, and either of the following conditions is true: * The length property of the XMLList object is 0, and the other object is undefined. * The length property of the XMLList object is 1, and one element of the XMLList object matches the other operand." In our case, the length "property" (poor choice of words, since .length would return another XMLList) is 1, so the result will be based on a comparison between the one element of the XMLList, which is an XML object, and the other operand, which is null. So what does the equality operator doc say about XML objects to non-XML operands? It says the result is false unless "one operand is of type XML with simple content (hasSimpleContent() == true), and after both operands are converted to strings with the toString() method, the resulting strings match." So here, we do in fact have an XML object, the "inner" node, with simple content, i.e. the String "null". And when you convert that XML object to a string with the toString() method, you will simply have the string "null". And when you convert the OTHER OPERAND, which is null, to a string, you will also have "null", and therefore the equality operation will return true. So there you have it. It's working the way it was designed to work. A null is converted to the string "null" for the purpose of an equality comparison. Personally, I think it was a poorly thought-out design decision, but hey, what do I know? Maybe they had their reasons. I think the language designers should have made a separate rule or two to cover cases when one operand is null or undefined and the other is not. And as a side note, if the strict equality operator (===) is used, then the expression: xmlList === null evaluates to false, as you would expect.