I was recently surprised to find that the in keyword in AS3 has two meanings. I had been using it as part of the for-in and for-each loop syntax for a long time. Turns out it is an operator of its own. Read on for details.

Here are the usual loops that use the in keyword:

for (var prop:String in obj)
{
	trace("object has a property named " + prop + " with the value " + obj[prop]);
}
for each (var val:int in arr)
{
	trace("array has the value " + val);
}

These are likely common knowledge of AS3 programmers. However, I’ve never yet seen anyone’s AS3 code that included the other usage of in. It is useful as a cleanup, mostly. Consider this function:

function hasProperty(obj:Object, prop:String): Boolean
{
	return obj[prop] !== undefined;
}

This can be rewritten with the in operator:

function hasProperty(obj:Object, prop:String): Boolean
{
	return prop in obj;
}

Here we see the in operator used as a test to see if obj has the property prop. How useful is this though? One thing you might guess that it would do is to protect you from indexing a null or undefined object. You’d guess wrong. You will get:

TypeError: Error #1009

How about checking for a property you’ve set explicitly to the value undefined instead of using the delete operator? Consider this snippet:

var obj:Object = {name:"john"};
delete obj.name;
 
var obj2:Object = {name:"john"};
obj2.name = undefined;
 
trace(obj.name);
trace(obj2.name);
 
trace("name" in obj);
trace("name" in obj2);

What does this print? Well, using the delete operator will remove the key-value pair from the object. This causes the property to be removed and the result of any query of it to return undefined. So the first two trace statements print “undefined”. The second two show the usefulness of the in operator. Here is the full output:

undefined
undefined
false
true

We may now test more thoroughly if an object has a property. This is yet another level of inspection we can perform on an object. Here are the tiers:

obj.prop != null; // level 1: check if the object has null or undefined at the key "prop"
obj.prop !== undefined; // level 2: check if the object has a non-undefined object the key "prop"
"prop" in obj; // level 3: check if the object has the key "prop" at all

This also shows us that our first implementation of hasProperty was incorrect.

Use this knowledge to decide just what level of checking you want to do on your objects. All three are appropriate for different situations. Make sure you’re using the right one!