Table of Contents

5.4 The Equality and Inequality Operators

We use the equality operator (= =) to test whether two expressions have the same value. An equality test takes the general form:

operand1 =  = operand2

where operand1 and operand2 can be any valid expression. The equality operator can compare operands of any type. When operand1 and operand2 are equal, the expression returns the Boolean value true; when they differ, it returns the Boolean value false. For example:

// Store the value 2 in x.
var x = 2;
// Is x equal to 1?
if (x =  = 1) {
  // false; nothing is displayed
  trace("x is equal to 1);
}
// Is x equal to 2?
if (x =  = 2) {
  // true; message is displayed
  trace("x is equal to 2);
}

The equality operator is created using two equals signs in a row (= =). It determines whether two expressions are equal, and it should not be confused with the assignment operator (=), which is a single equals sign used to assign a new value to a variable. Flash MX also supports the strict equality operator, created using three equals signs (= = =). See the Section 5.5 later in this chapter.

Consider this example:

if (x = 5) {
  trace("x is equal to 5")
}

This example does not check whether x equals 5. Instead, it sets x equal to 5. It then evaluates the variable x as a Boolean expression, which yields true (positive numbers convert to the Boolean value true). Here is what our example looks like to the interpreter:

x = 5;
if (x) {
  trace("x is equal to 5")
}

The proper construction is as follows:

// Use =  = instead of =
if (x =  = 5) {  
  trace("x is equal to 5")
}

5.4.1 Primitive Datatype Equality

For the primitive datatypes, the result of most equality tests is fairly intuitive. Table 5-2 lists the rules that govern equality for each primitive datatype.

Table 5-2. Equality of primitive datatypes

Type

Terms of equality (both operands must be of given type)

Number

If operand1 is the same number as operand2, the result is true. If both operands are +Infinity or both are -Infinity, the result is true. If both operands are either -0 or +0, the result is true. For all other combinations, including if either or both operands are NaN, the result is false:

1 =  = 4                 // false
4 =  = 4                 // true
NaN =  = NaN             // false
+Infinity = -Infinity  // false

String[1]

Performs case-sensitive string comparison. If operand1 and operand2 are strings of the same length that contain the exact same sequence of characters, the result is true; otherwise, the result is false:

"Flash" =  = "Flash"        // true
"O'Reilly" =  = "O Reilly"  // false
"Moock" =  = "moock"        // false ("m" and "M" differ)

Boolean

If both operands are true or both operands are false, the result is true; otherwise, the result is false:

true =  = true    // true
false =  = false  // true
true =  = false   // false

undefined

If both operands are undefined, or if one operand is undefined and the other is null, the result is true; otherwise, the result is false.

null

If both operands are null, or if one operand is undefined and the other is null, the result is true; otherwise, the result is false.

Composite datatypes

See Section 5.4.2.

[1] Flash 4's string equality operator, eq, is deprecated. The = = operator should be used in Flash 5 and Flash MX.

5.4.2 Composite Datatype Equality

As shown in Section 3.6 in Chapter 3, variables containing composite data (objects, arrays, functions, or movie clips) store references to the data and not the data itself; hence, it is possible for two variables to refer to the same underlying item. Two such operands are considered equal if and only if they refer to the same underlying composite datum, not if the operands refer to two different items that contain identical contents. Even if two operands can be converted to the same primitive value, they are not necessarily considered equal.

The following examples illustrate how ActionScript compares the references that point to the composite data, not the data itself. In the first example, the operands (nameList1 and nameList2) refer to arrays that have the same elements but are actually two distinct arrays. The references are therefore different, and the comparison evaluates to false:

nameList1 = ["Linkovich", "Harris", "Sadler"];
nameList2 = ["Linkovich", "Harris", "Sadler"];
// The two arrays are not considered equal, so
// the trace( ) statement doesn't execute.
if (nameList1 =  = nameList2) {
  trace("They're the same");
}

In this example, cities and canadianCities both refer to the same array, so they are equal:

canadianCities = ["Toronto","Montreal","Vancouver"];
cities = canadianCities;
// The two arrays are considered equal, so 
// the trace( ) statement does execute.
if (cities =  = canadianCities) {
  trace("They're the same");
}

In this example, myFirstBall and mySecondBall have the same constructor (i.e., are both objects derived from the same class), but they exist as separate (unequal) instances:

function Ball ( ) {
  // ...initialization code goes here...
}
myFirstBall = new Ball( );
mySecondBall = new Ball( );
myFirstBall =  = mySecondBall  // false

As shown in Chapter 3, composite data values are compared by reference, not by value.

To duplicate an array's contents without copying the array reference, we can use the Array.slice( ) method. In this example, we copy the elements from the dishes array into kitchenItems:

dishes = [ "cup", "plate", "spoon" ];
kitchenItems = dishes.slice(0, dishes.length);
trace(kitchenItems =  = dishes);  // Displays: false

Now kitchenItems and dishes each contain their own private copy of the array elements and can alter them without affecting each other.

5.4.3 Equality and Datatype Conversion

We've seen the results of equality tests when the two operands have the same datatype, but what happens when we compare operands of different datatypes, such as a string and a number? For example:

"asdf" =  = 13;

When the operands have disparate datatypes, the interpreter performs a type conversion before performing the comparison. Here are the rules the interpreter follows:

  1. If both operands are of the same type, compare them and return the result. (If null is compared to undefined, true is returned.)

  2. If one operand is a number and the other operand is a string, convert the string to a number and go back to step 1.

  3. If one operand is a Boolean, convert the Boolean to a number (true = 1, false = 0) and go back to step 1.

  4. If one operand is an object, invoke the valueOf( ) method of the object to convert it to a primitive type. Return false if this is not possible. Otherwise, go back to step 1.

  5. Return false if the previous steps don't obtain a valid result.

Note that if one operand is an object and the other is a Boolean, the Boolean will be converted to a number and compared to the primitive value of the object. This means that someObject = = true is normally false, even if someObject exists, because someObject is converted to a number or a string for the comparison, while true is converted to the number 1. To force someObject to be treated as a Boolean in a comparison, use the Boolean( ) function, like this:

Boolean(someObject) =  = true    // Returns true if someObject exists, 
                               // or false if it doesn't

Conversions caused by equality operations favor the number type. If you're wondering about the results of the various type conversions just described, see Section 3.4 in Chapter 3. Note that type conversions performed during a comparison do not alter the original item's stored value or datatype. The results of the temporary conversion are discarded once the expression has been evaluated.

5.4.4 The Inequality Operator

The inequality operator (also called the does-not-equal or not-equal-to operator) returns the opposite Boolean result of the equality operator. It is often more readable to say, "If x is not equal to y, do this," than to say, "If x is equal to y, don't do anything, otherwise do this," as shown later in Example 5-2. An inequality test takes the general form:

operand1 != operand2

For example:

var a = 5;
var b = 6;
var c = 6;
a != b  // true
b != c  // false

The inequality operator follows the same type conversion rules as the equality operator and always yields the opposite result, including when NaN is used as an operand:

NaN != 7    // true
NaN != NaN  // true!

In some languages, including Flash 4 ActionScript, the <> operator is used as the inequality operator. Flash 4 used the deprecated ne operator for string comparisons. In Flash 5 and Flash MX, != should be used in lieu of <> and ne for comparisons, regardless of the operands' datatypes. See also the logical NOT operator (!) discussed later in this chapter.

5.4.5 Common Uses of Equality Operations

We'll frequently use equality operations to form Boolean expressions within conditional statements or to assign a Boolean value to a variable. Example 5-2 shows both situations and demonstrates the != and = = operators in action.

Example 5-2. Using the equality and inequality operators
version = getVersion( );      // Retrieve Player version
// Check if the string "WIN" is in version. If so, 
// set isWin to true, otherwise set it to false.
isWin = (version.indexOf("WIN") != -1);  
// If isWin is true...
if (isWin =  = true) {       
  // ...perform Windows-specific actions here.
  trace("Please use IE5 or later on Windows.");
}

Experienced programmers will be quick to point out that we could have reduced if (isWin = = true) to if (isWin), because isWin holds a Boolean value, which is what the if statement expects. While that's quite right, it doesn't make for a good example of the equality operator, now does it? Furthermore, new programmers usually find the more verbose form clearer. Both approaches are perfectly acceptable. We'll cover this topic in more detail in Chapter 7.


Table of Contents