home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeActionScript: The Definitive GuideSearch this book

5.4. The Equality and Inequality Operators

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

operand1 == operand2

where operand1 and operand2 may 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:

var x = 2;
x == 1     // false
x == 2     // true

TIP

The equality operator is created using two equal signs in a row (==). It determines whether two expressions are equal and should not be confused with the assignment operator (=) which is used to assign a variable a new value.

Consider this example:

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

The preceding example does not check whether x equals 5. Instead, it sets x equal to 5. The proper expression 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*

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" are
                          // not the same character)

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 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, "Composite Datatype Equality".

* Flash 4's string equality operator was eq. While eq is supported in Flash 5 for backward compatibility, it is not recommended unless exporting to Flash 4 .swf format.

5.4.2. Composite Datatype Equality

Because variables containing composite data (objects, arrays, functions, or movie clips) store references to the data and not the data itself, 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 data, 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 still 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"];
nameList1 == nameList2  // false

In this example, cities and canadianCities both refer to the same array:

canadianCities = ["Toronto","Montreal","Vancouver"];
cities = canadianCities;
cities == canadianCities  // true

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:

myFirstBall = new Ball( );
mySecondBall = new Ball( );
myFirstBall == mySecondBall  // false

Thus, equality tests for composite data values are said to be compared by reference, not by value. For more information on the difference, see Section 15.1, "Copying, Comparing, and Passing Data" in Chapter 15, "Advanced Topics".

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 contains its 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, as in:

"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, we 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, "Datatype Conversion" in Chapter 3, "Data and Datatypes".

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 does-not-equal or not-equal-to operator (or inequality 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. The inequality operator 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 using NaN as one operand:

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

In some languages, including Flash4 ActionScript, the <> operator is used as the inequality operator. See also the NOT operator (!) discussed later.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.