By now you’ve certainly heard of the is operator in AS3. It’s the replacement for instanceof in AS2. But the two are not the same! Don’t make this mistake…

The instanceof operator in AS2 simply told you if the first operand was an instance of the second:

var p:Point = new Point(2, 3);
trace(p instanceof Point); // true
trace(p instanceof Number); // false

What could be simpler? With AS3 the instanceof operator is now deprecated, but only generated a compiler warning if you actually use it. AS3 now has the is operator, which is 8 fewer letters to type. But it’s more than that! The is operator is not exactly the same as the instanceof operator. Even the ActionScript 2.0 Migration section of the Flash 10 docs are misleading when they say:

Although the instanceof operator is available, it only checks the prototype
chain, which is not the primary inheritance mechanism in ActionScript 3.0. Use
the is operator to check whether an object is a member of a specific data type.

Considering the above documentation from Adobe, guess what this would print:

var n:Number = 3;
var n2:Number = 3.5;
trace(n is Number);
trace(n2 is Number);
trace(n is int);
trace(n2 is int);

It would seem that both n and n2 are of type Number so the first two traces should print true. Since Number and int are different types and any given variable can only be of one type, it would seem that the latter two traces should print false. This is wrong though. In fact, they don’t even both print the same result:

var n:Number = 3;
var n2:Number = 3.5;
trace(n is Number); // true
trace(n2 is Number); // true
trace(n is int); // true
trace(n2 is int); // false!

This is why I have title the article using the word “magic.” The is operator does not simply check the type of the operands and do a simple comparison as the Adobe docs would lead you to believe, but instead makes a special case out of the Number class and determines if the Number has any fractional part!

To Adobe’s credit, they did specify a little more in the Operators section of the Flash 10 docs for the “is” operator. Here’s an excerpt:

Evaluates whether an object is compatible with a specific data type, class, or
interface. Use the is operator instead of the instanceof operator for type
comparisons. You can also use the is operator to check whether an object
implements an interface.

But even here the documentation is quite ambiguous. They plainly say to use the is operator in place of instanceof without specifying any difference. Vaguely, the documentation states that the is operator checks if the first operand is “compatible” with a type, class, or interface. What does “compatible” mean? They don’t say.

There is a good side to all of this though, you now have a nice way to check if a Number is an integer rather than clumsy arithmetic:

function isInteger(n:Number): Boolean
{
	return n is int;
}

That’s a very clean function that you should probably inline into your code. Just beware that if you’re expecting the is operator to strictly check types, you’re setting yourself up for some pretty cryptic bugs. Lastly, I should mention that even though the instanceof operator is deprecated and you’ll get a warning by default, you can still use it to get that strict type checking you used to:

var n:Number = 3;
var n2:Number = 3.5;
trace(n instanceof Number); // true
trace(n2 instanceof Number); // true
trace(n instanceof int); // false!
trace(n2 instanceof int); // false!