Null, undefined and NaN
A newbie in ActionScript3 might wonder why there are 3 different values which mean "nothing". I'll try to explain the difference.
Something is null when it points to nothing. If you remember that by saying
var p: Point = new Point();
we create a reference (pointer) p
to a position in memory which has the created Point
object. This pointer is typed so can reference only objects of type Point. If we write
p = 42 as Point;
flash can't convert 42 to Point
so p
just points to nothing in memory thus it is null.
If we write something like
var i:int = (new Point()) as int;
i will be 0 because int variable is of so-called simple type and contains its value not points to some memory space.
But what about undefined? Remember that in ActionScript we can have dynamic classes and untyped variables. For example this is an untyped variable definition:
var untyped: *;
While it's not set it is undefined because it neither points to anything nor it contains a simple value. It is just not defined yet. All typed variables have default values which is usually null. Also we get undefined when referencing a non-existing property of a dynamic object.
trace({}.x); // empty Object
trace([][1]); // empty Array
both will trace undefined. This is quite interesting, because here if you don't understand the difference between null and undefined you can get unusual results. Let's check an example.
var o: Object = {x: null};
trace(o.x);
trace(!o.x);
trace(o.y);
trace(!o.y);
This will output:
null
true
undefined
true
x property exists in object o but it points to nothing, but y property doesn't exist at all. If you test something for existence using this approach you are missing the point. You should use === instead, because
null == undefined; // true
null === undefined; // false
Now what is NaN. NaN states for Not a Number. It's a value which a variable of type Number can hold meaning that it holds something which is not a number. This is how you can get NaN:
Number("hello");
0/0;
Math.sqrt(-1);
The only way you can check if your variable holds NaN is isNaN()
global function. You can't say
something == NaN;
because comparing to NaN always results in false. Even
NaN == NaN
is false.
There's another value for Numbers you should know — Infinity. You can get it if you divide something by 0.
OK, let's do our final test.
private var undef: *;
trace({}.x); // undefined
trace(undef); // undefined
trace([][1]); // undefined
trace(Number("hello")); // NaN
trace(0/0); // NaN
trace(Math.sqrt(-1)); // NaN
trace(1/0); // Infinity
trace(NaN == undefined); // false
trace(NaN === undefined); // false
trace(null == undefined); // true
trace(null === undefined); // false
trace(NaN == NaN); // false
trace(NaN === NaN); // false
trace(null == null); // true
trace(null === null); // true
trace(undefined == undefined); // true
trace(undefined === undefined); // true