JavaScript – Operator Overview

Operators are used for JavaScript’s arithmetic expressions,
comparison expressions, logical expressions, assignment expressions,
and more. Table 4-1 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-1 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-1. JavaScript operators

Operator Operation A N Types
++ Pre- or post-increment R 1 lvalnum
-- Pre- or post-decrement R 1 lvalnum
- Negate number R 1 numnum
+ Convert to number R 1 numnum
~ Invert bits R 1 intint
! Invert boolean value R 1 boolbool
delete Remove a property R 1 lvalbool
typeof Determine type of operand R 1 anystr
void Return undefined value R 1 anyundef
*, /, % Multiply, divide, remainder L 2 num,numnum
+, - Add, subtract L 2 num,numnum
+ Concatenate strings L 2 str,strstr
<< Shift left L 2 int,intint
>> Shift right with sign extension L 2 int,intint
>>> Shift right with zero extension L 2 int,intint
<, <=, >, >= Compare in numeric order L 2 num,numbool
<, <=, >, >= Compare in alphabetic order L 2 str,strbool
instanceof Test object class L 2 obj,funcbool
in Test whether property exists L 2 str,objbool
== Test for equality L 2 any,anybool
!= Test for inequality L 2 any,anybool
=== Test for strict equality L 2 any,anybool
!== Test for strict inequality L 2 any,anybool
& Compute bitwise AND L 2 int,intint
^ Compute bitwise XOR L 2 int,intint
| Compute bitwise OR L 2 int,intint
&& Compute logical AND L 2 any,anyany
|| Compute logical OR L 2 any,anyany
?: Choose 2nd or 3rd operand R 3 bool,any,anyany
= Assign to a variable or property R 2 lval,anyany
*=, /=, %=, +=, Operate and assign R 2 lval,anyany
-=, &=, ^=, |=,        
<<=, >>=, >>>=        
, Discard 1st operand, return second L 2 any,anyany

Number of Operands

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.

Operand and Result Type

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-1 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.

Lvalues

Notice that the assignment operators and a few of the other
operators listed in Table 4-1 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.

Operator Side Effects

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.

Operator Precedence

The operators listed in Table 4-1 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-1. 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.

Operator Associativity

In Table 4-1, 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.

Order of Evaluation

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.

Comments are closed.