Friday, November 23, 2007

String Comparisons (for Equality) in ActionScript 3

While Java and ActionScript have much in common in terms of syntax, their respective handling of String comparisons are a little different.

Many of us learned early in our Java experience that we should generally compare Strings in Java using the String.equals() method rather than using the normal Java equality operator (==) because normally we wanted the equals() method behavior rather than the == behavior. The reason for this is normally we want to know if two Strings consist of the same characters in the same positions and equals provides true if that is the case. Using Java's == operator on the other hand, only returns true in a comparison of Strings if they are literally the same object and not just the same characters.

When using ActionScript, the developer's "default String comparison thinking" shifts from typically using equals to typically using ==. In fact, ActionScript's String class does not even have an equals() method. ActionScript also supports a comparison operator with three equals signs (===), but this seems to behave the same for most String comparison cases I have tried, so I typically stick to the two equals signs version (==).

The following code example (StringComparison.mxml) exercises the == operator to compare two ActionScript Strings.

<mx:Application xmlns:mx=""
width="500" height="300">

* To compile solely this Flex application from the command line, use
* mxmlc -strict=true StringComparison.mxml
* This application demonstrates use of and nuances associated with
* ActionScript 3 String comparisons.
private const firstString:String = "Privacy";

* Compare string entered into input text (providedString) to constant
* String assigned to firstString.
private function compareString():void
const textInputString:String = providedString.text;
if ( textInputString == firstString )
statusValue.text = "Same Strings!";
statusValue.setStyle("color", "0x00FF00");
statusResultValue.setStyle("color", "0x00FF00");
statusValue.text = textInputString
+ " is not the same String.";
statusValue.setStyle("color", "0xFF0000");
statusResultValue.setStyle("color", "0xFF0000");
statusResultValue.text = String(textInputString == firstString);

<mx:HDividedBox id="mainBox" width="100%" height="100%">
<mx:VBox id="interactiveComparisons" width="50%" height="100%">
<mx:Label id="stringPrompt"
text="Enter a String to compare to '{firstString}':" />
<mx:TextInput id="providedString" enter="compareString();"/>
<mx:Label id="statusLabel" text="Status" />
<mx:Label id="statusValue" text="None tried" />
<mx:Label id="statusResultLabel" text="Status Result" />
<mx:Label id="statusResultValue" text="None tried" />


The output for this code when compiled and run is shown in the next two screen shots (click on each image to see larger version):

Output When Entered String is NOT a Match

Output When Entered String IS a Match

If you switch the one highlighted line of code from using == to using ===, the resulting output behavior does not change and the output snap shots would match those above. This is because the comparison ends up comparing Strings, so the type is the same. The only way to see a difference between == and === is to turn off strict compiling and to try to test two different data types with the same core value.

According to MDC JavaScript 1.5 documentation, the === operator checks data type in addition to content and that additional check of type is what separates it from ==. However, with ActionScript 3's more strict data type checking, the compiler often reports this anyway (as long as you compile in strict mode, the default) and I have not found a realistic case where a String comparison in ActionScript differs between == and ===. It might be useful to differentiate between == and === when running non-strict code to ensure that data types are the same as well as content, but I'd normally rather run in strict mode and have the compiler checking this all the time.

If you have run into a realistic situation in which an ActionScript String comparison has differed because of your choice of == versus ===, please feel free to add that to the comments section below. The only way I can see that this would happen is if the code was compiled explicitly in non-strict mode. Because I always compile in strict mode (code example shows that it should be compiled with mxmlc -strict=true StringComparison.mxml), I never see a difference between == and ===. Note that the default is to strictly compile, so you'd need to explicitly state -strict=false to the compiler to see a difference between == and ===.

UPDATE: See another blog entry for additional details on == and ===.

No comments: