Operators are used for JavaScript’s arithmetic expressions, comparison expressions, logical expressions, assignment expressions, and more. Table 4-2 summarizes the operators and serves as a convenient reference.
Note that most operators are represented by punctuation
characters such as +
and =
. Some, however, are represented by
keywords such as delete
and
instanceof
. Keyword operators are
regular operators, just like those expressed with punctuation; they
simply have a less succinct syntax.
Table 4-2 is organized by operator precedence. The operators listed first have higher precedence than those listed last. Operators separated by a horizontal line have different precedence levels. The column labeled A gives the operator associativity, which can be L (left-to-right) or R (right-to-left), and the column N specifies the number of operands. The column labeled Types lists the expected types of the operands and (after the → symbol) the result type for the operator. The subsections that follow the table explain the concepts of precedence, associativity, and operand type. The operators themselves are individually documented following that discussion.
Table 4-2. JavaScript operators
Operator | Operation | A | N | Types |
---|---|---|---|---|
++ | Pre- or post-increment | R | 1 | lval→num |
-- | Pre- or post-decrement | R | 1 | lval→num |
- | Negate number | R | 1 | num→num |
+ | Convert to number | R | 1 | num→num |
~ | Invert bits | R | 1 | int→int |
! | Invert boolean value | R | 1 | bool→bool |
delete | Remove a property | R | 1 | lval→bool |
typeof | Determine type of operand | R | 1 | any→str |
void | Return undefined value | R | 1 | any→undef |
* , / , % | Multiply, divide, remainder | L | 2 | num,num→num |
+ , - | Add, subtract | L | 2 | num,num→num |
+ | Concatenate strings | L | 2 | str,str→str |
<< | Shift left | L | 2 | int,int→int |
>> | Shift right with sign extension | L | 2 | int,int→int |
>>> | Shift right with zero extension | L | 2 | int,int→int |
< , <= ,> , >= | Compare in numeric order | L | 2 | num,num→bool |
< , <= ,> , >= | Compare in alphabetic order | L | 2 | str,str→bool |
instanceof | Test object class | L | 2 | obj,func→bool |
in | Test whether property exists | L | 2 | str,obj→bool |
== | Test for equality | L | 2 | any,any→bool |
!= | Test for inequality | L | 2 | any,any→bool |
=== | Test for strict equality | L | 2 | any,any→bool |
!== | Test for strict inequality | L | 2 | any,any→bool |
& | Compute bitwise AND | L | 2 | int,int→int |
^ | Compute bitwise XOR | L | 2 | int,int→int |
| | Compute bitwise OR | L | 2 | int,int→int |
&& | Compute logical AND | L | 2 | any,any→any |
|| | Compute logical OR | L | 2 | any,any→any |
?: | Choose 2nd or 3rd operand | R | 3 | bool,any,any→any |
= | Assign to a variable or property | R | 2 | lval,any→any |
*= , /= , %= , += , | Operate and assign | R | 2 | lval,any→any |
-= , &= , ^= , |= , | ||||
<<= , >>= , >>>= | ||||
, | Discard 1st operand, return second | L | 2 | any,any→any |
Operators can be categorized based on the number of operands
they expect (their arity). Most JavaScript
operators, like the *
multiplication operator, are binary operators
that combine two expressions into a single, more complex expression.
That is, they expect two operands. JavaScript also supports a number
of unary operators, which convert a single
expression into a single, more complex expression. The −
operator in the expression −x
is a unary operator that performs the
operation of negation on the operand x
. Finally, JavaScript supports one
ternary operator, the conditional operator
?:
, which combines three
expressions into a single expression.
Some operators work on values of any type, but most expect their operands to be of a specific type, and most operators return (or evaluate to) a value of a specific type. The Types column in Table 4-2 specifies operand types (before the arrow) and result type (after the arrow) for the operators.
JavaScript operators usually convert the type (see Type Conversions) of their operands as needed. The
multiplication operator *
expects
numeric operands, but the expression "3" *
"5"
is legal because JavaScript can convert the operands
to numbers. The value of this expression is the number 15, not the
string “15”, of course. Remember also that every JavaScript value is
either “truthy” or “falsy,” so operators that expect boolean
operands will work with an operand of any type.
Some operators behave differently depending on the type of the
operands used with them. Most notably, the +
operator adds numeric operands but
concatenates string operands. Similarly, the comparison operators
such as <
perform comparison
in numerical or alphabetical order depending on the type of the
operands. The descriptions of individual operators explain their
type-dependencies and specify what type conversions they
perform.
Notice that the assignment operators and a few of the other
operators listed in Table 4-2 expect an operand of type lval
. lvalue is a
historical term that means “an expression that can legally appear on
the left side of an assignment expression.” In JavaScript,
variables, properties of objects, and elements of arrays are
lvalues. The ECMAScript specification allows built-in
functions to return lvalues but does not define any functions that
behave that way.
Evaluating a simple expression like 2
* 3
never affects the state of your program, and any
future computation your program performs will be unaffected by that
evaluation. Some expressions, however, have side
effects, and their evaluation may affect the result of
future evaluations. The assignment operators are the most obvious
example: if you assign a value to a variable or property, that
changes the value of any expression that uses that variable or
property. The ++
and --
increment and decrement operators are
similar, since they perform an implicit assignment. The delete
operator also has side effects:
deleting a property is like (but not the same as) assigning undefined
to the property.
No other JavaScript operators have side effects, but function invocation and object creation expressions will have side effects if any of the operators used in the function or constructor body have side effects.
The operators listed in Table 4-2 are arranged in order from high precedence to low precedence, with horizontal lines separating groups of operators at the same precedence level. Operator precedence controls the order in which operations are performed. Operators with higher precedence (nearer the top of the table) are performed before those with lower precedence (nearer to the bottom).
Consider the following expression:
w
=
x
+
y
*
z
;
The multiplication operator *
has a higher precedence than the
addition operator +
, so the
multiplication is performed before the addition. Furthermore, the
assignment operator =
has the
lowest precedence, so the assignment is performed after all the
operations on the right side are completed.
Operator precedence can be overridden with the explicit use of parentheses. To force the addition in the previous example to be performed first, write:
w
=
(
x
+
y
)
*
z
;
Note that property access and invocation expressions have higher precedence than any of the operators listed in Table 4-2. Consider this expression:
typeof
my
.
functions
[
x
](
y
)
Although typeof
is one of
the highest-priority operators, the typeof
operation is performed on the
result of the two property accesses and the function
invocation.
In practice, if you are at all unsure about the precedence of your operators, the simplest thing to do is to use parentheses to make the evaluation order explicit. The rules that are important to know are these: multiplication and division are performed before addition and subtraction, and assignment has very low precedence and is almost always performed last.
In Table 4-2, the column labeled A specifies the associativity of the operator. A value of L specifies left-to-right associativity, and a value of R specifies right-to-left associativity. The associativity of an operator specifies the order in which operations of the same precedence are performed. Left-to-right associativity means that operations are performed from left to right. For example, the subtraction operator has left-to-right associativity, so:
w
=
x
-
y
-
z
;
is the same as:
w
=
((
x
-
y
)
-
z
);
On the other hand, the following expressions:
x
=
~-
y
;
w
=
x
=
y
=
z
;
q
=
a
?
b
:
c
?
d
:
e
?
f
:
g
;
are equivalent to:
x
=
~
(
-
y
);
w
=
(
x
=
(
y
=
z
));
q
=
a
?
b
:
(
c
?
d
:
(
e
?
f
:
g
));
because the unary, assignment, and ternary conditional operators have right-to-left associativity.
Operator precedence and associativity specify the order in
which operations are performed
in a complex expression, but they do not specify the order in which
the subexpressions are evaluated. JavaScript always evaluates
expressions in strictly left-to-right order. In the expression
w=x+y*z
, for example, the
subexpression w
is evaluated
first, followed by x
, y
, and z
. Then the values of y
and z
are multiplied, added to the value of x
, and assigned to the variable or
property specified by expression w
. Adding parentheses to the expressions
can change the relative order of the multiplication, addition, and
assignment, but not the left-to-right order of evaluation.
Order of evaluation only makes a difference if any of the
expressions being evaluated has side effects that affect the value
of another expression. If expression x
increments a variable that is used by
expression z
, then the fact that
x
is evaluated before z
is important.
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.