This section describes JavaScript’s relational operators. These
operators test for a relationship (such as “equals,” “less than,” or
“property of”) between two values and return true
or false
depending on whether that relationship
exists. Relational expressions always evaluate to a boolean value, and
that value is often used to control the flow of program execution in
if
, while
, and for
statements (see Chapter 5). The subsections that follow document the
equality and inequality operators, the comparison operators, and
JavaScript’s other two relational operators, in
and instanceof
.
The ==
and ===
operators check whether two values are
the same, using two different definitions of sameness. Both
operators accept operands of any type, and both return true
if their operands are the same and
false
if they are different. The
===
operator is known as the
strict equality operator (or sometimes the identity operator), and
it checks whether its two operands are “identical” using a strict
definition of sameness. The ==
operator is known as the equality operator; it checks whether its
two operands are “equal” using a more relaxed definition of sameness
that allows type conversions.
JavaScript supports =
,
==
, and ===
operators. Be sure you understand the
differences between these assignment, equality, and strict equality
operators, and be careful to use the correct one when coding!
Although it is tempting to read all three operators “equals,” it may
help to reduce confusion if you read “gets or is assigned” for
=
, “is equal to” for ==
, and “is strictly equal to” for
===
.
The !=
and !==
operators test for the exact opposite
of the ==
and ===
operators. The !=
inequality
operator returns false
if two
values are equal to each other according to ==
and returns true
otherwise. The !==
operator returns false
if two values are strictly equal to
each other and returns true
otherwise. As you’ll see in Logical Expressions, the
!
operator computes the Boolean
NOT operation. This makes it easy to remember that !=
and !==
stand for “not equal to” and “not
strictly equal to.”
As mentioned in Immutable Primitive Values and Mutable Object References, JavaScript objects are compared by reference, not by value. An object is equal to itself, but not to any other object. If two distinct objects have the same number of properties, with the same names and values, they are still not equal. Two arrays that have the same elements in the same order are not equal to each other.
The strict equality operator ===
evaluates its operands, and then
compares the two values as follows, performing no type
conversion:
If the two values have different types, they are not equal.
If both values are
null
or both values areundefined
, they are equal.If both values are the boolean value
true
or both are the boolean valuefalse
, they are equal.If one or both values is
NaN
, they are not equal. TheNaN
value is never equal to any other value, including itself! To check whether a valuex
isNaN
, usex !== x
.NaN
is the only value ofx
for which this expression will be true.If both values are numbers and have the same value, they are equal. If one value is
0
and the other is-0
, they are also equal.If both values are strings and contain exactly the same 16-bit values (see the sidebar in Text) in the same positions, they are equal. If the strings differ in length or content, they are not equal. Two strings may have the same meaning and the same visual appearance, but still be encoded using different sequences of 16-bit values. JavaScript performs no Unicode normalization, and a pair of strings like this are not considered equal to the
===
or to the==
operators. SeeString
.
locale
Compare()
in Part III for another way to compare strings.If both values refer to the same object, array, or function, they are equal. If they refer to different objects they are not equal, even if both objects have identical properties.
The equality operator ==
is
like the strict equality operator, but it is less strict. If the
values of the two operands are not the same type, it attempts some
type conversions and tries the comparison again:
If the two values have the same type, test them for strict equality as described above. If they are strictly equal, they are equal. If they are not strictly equal, they are not equal.
If the two values do not have the same type, the
==
operator may still consider them equal. Use the following rules and type conversions to check for equality:If one value is
null
and the other isundefined
, they are equal.If one value is a number and the other is a string, convert the string to a number and try the comparison again, using the converted value.
If either value is
true
, convert it to 1 and try the comparison again. If either value isfalse
, convert it to 0 and try the comparison again.If one value is an object and the other is a number or string, convert the object to a primitive using the algorithm described in Object to Primitive Conversions and try the comparison again. An object is converted to a primitive value by either its
toString()
method or itsvalueOf()
method. The built-in classes of core JavaScript attemptvalueOf()
conversion beforetoString()
conversion, except for the Date class, which performstoString()
conversion. Objects that are not part of core JavaScript may convert themselves to primitive values in an implementation-defined way.Any other combinations of values are not equal.
As an example of testing for equality, consider the comparison:
"1"
==
true
This expression evaluates to true
, indicating that these very
different-looking values are in fact equal. The boolean value
true
is first converted to the
number 1, and the comparison is done again. Next, the string
"1"
is converted to the number 1.
Since both values are now the same, the comparison returns true
.
The comparison operators test the relative order (numerical or alphabetics) of their two operands:
- Less than (
<
) The
<
operator evaluates totrue
if its first operand is less than its second operand; otherwise it evaluates tofalse
.- Greater than (
>
) The
>
operator evaluates totrue
if its first operand is greater than its second operand; otherwise it evaluates tofalse
.- Less than or equal (
<=
) The
<=
operator evaluates totrue
if its first operand is less than or equal to its second operand; otherwise it evaluates tofalse
.- Greater than or equal (
>=
) The
>=
operator evaluates totrue
if its first operand is greater than or equal to its second operand; otherwise it evaluates tofalse
.
The operands of these comparison operators may be of any type. Comparison can be performed only on numbers and strings, however, so operands that are not numbers or strings are converted. Comparison and conversion occur as follows:
If either operand evaluates to an object, that object is converted to a primitive value as described at the end of Object to Primitive Conversions: if its
valueOf()
method returns a primitive value, that value is used. Otherwise, the return value of itstoString()
method is used.If, after any required object-to-primitive conversion, both operands are strings, the two strings are compared, using alphabetical order, where “alphabetical order” is defined by the numerical order of the 16-bit Unicode values that make up the strings.
If, after object-to-primitive conversion, at least one operand is not a string, both operands are converted to numbers and compared numerically.
0
and-0
are considered equal.Infinity
is larger than any number other than itself, and-Infinity
is smaller than any number other than itself. If either operand is (or converts to)NaN
, then the comparison operator always returnsfalse
.
Remember that JavaScript strings are sequences of 16-bit
integer values, and that string comparison is just a numerical
comparison of the values in the two strings. The numerical encoding
order defined by Unicode may not match the traditional collation
order used in any particular language or locale. Note in particular
that string comparison is case-sensitive, and all capital ASCII
letters are “less than” all lowercase ASCII letters. This rule can
cause confusing results if you do not expect it. For example,
according to the <
operator,
the string “Zoo” comes before the string “aardvark”.
For a more robust string-comparison algorithm, see the
String.localeCompare()
method,
which also takes locale-specific definitions of alphabetical order
into account. For case-insensitive comparisons, you must first
convert the strings to all lowercase or all uppercase using String.toLowerCase()
or String.toUpperCase()
.
Both the +
operator and the
comparison operators behave differently for numeric and string
operands. +
favors strings: it
performs concatenation if either operand is a string. The comparison
operators favor numbers and only perform string comparison if both
operands are strings:
1
+
2
// Addition. Result is 3.
"1"
+
"2"
// Concatenation. Result is "12".
"1"
+
2
// Concatenation. 2 is converted to "2". Result is "12".
11
<
3
// Numeric comparison. Result is false.
"11"
<
"3"
// String comparison. Result is true.
"11"
<
3
// Numeric comparison. "11" converted to 11. Result is false.
"one"
<
3
// Numeric comparison. "one" converted to NaN. Result is false.
Finally, note that the <=
(less than or equal) and >=
(greater than or equal) operators do
not rely on the equality or strict equality operators for
determining whether two values are “equal.” Instead, the
less-than-or-equal operator is simply defined as “not greater than,”
and the greater-than-or-equal operator is defined as “not less
than.” The one exception occurs when either operand is (or converts
to) NaN
, in which case all four
comparison operators return false
.
The in
operator expects a
left-side operand that is or can be converted to a string. It
expects a right-side operand that is an object. It evaluates to
true
if the left-side value is
the name of a property of the right-side object. For
example:
var
point
=
{
x
:
1
,
y
:
1
};
// Define an object
"x"
in
point
// => true: object has property named "x"
"z"
in
point
// => false: object has no "z" property.
"toString"
in
point
// => true: object inherits toString method
var
data
=
[
7
,
8
,
9
];
// An array with elements (indices) 0, 1, and 2
"0"
in
data
// => true: array has an element "0"
1
in
data
// => true: numbers are converted to strings
3
in
data
// => false: no element 3
The instanceof
operator
expects a left-side operand that is an object and a right-side
operand that identifies a class of objects. The operator evaluates
to true
if the left-side object
is an instance of the right-side class and evaluates to false
otherwise. Chapter 9 explains that, in JavaScript, classes of
objects are defined by the constructor function that initializes them. Thus,
the right-side operand of instanceof
should be a function. Here are
examples:
var
d
=
new
Date
();
// Create a new object with the Date() constructor
d
instanceof
Date
// Evaluates to true; d was created with Date()
d
instanceof
Object
// Evaluates to true; all objects are instances of Object
d
instanceof
Number
// Evaluates to false; d is not a Number object
var
a
=
[
1
,
2
,
3
];
// Create an array with array literal syntax
a
instanceof
Array
// Evaluates to true; a is an array
a
instanceof
Object
// Evaluates to true; all arrays are objects
a
instanceof
RegExp
// Evaluates to false; arrays are not regular expressions
Note that all objects are instances of Object
. instanceof
considers the “superclasses”
when deciding whether an object is an instance of a class. If the
left-side operand of instanceof
is not an object, instanceof
returns false
. If the right-hand
side is not a class of objects, it throws a TypeError
.
In order to understand how the instanceof
operator works, you must
understand the “prototype chain.” This is JavaScript’s inheritance
mechanism, and it is described in Inheritance. To
evaluate the expression o instanceof
f
, JavaScript evaluates f.prototype
, and then looks for that value
in the prototype chain of o
. If
it finds it, then o is an instance of f (or of a
subclass of f) and the operator returns true
. If f.prototype
is not one of the values in
the prototype chain of o
, then
o
is not an instance of f and
instanceof
returns false
.
Get JavaScript: The Definitive Guide, 6th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.