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

## 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" *`

is legal because JavaScript can convert the operands

"5"

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`

never affects the state of your program, and any

* 3

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 aresimilar, 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.