Operator Overview

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

OperatorOperationANTypes
++Pre- or post-incrementR1lvalnum
--Pre- or post-decrementR1lvalnum
-Negate numberR1numnum
+Convert to numberR1numnum
~Invert bitsR1intint
!Invert boolean valueR1boolbool
deleteRemove a propertyR1lvalbool
typeofDetermine type of operandR1anystr
voidReturn undefined valueR1anyundef
*, /, %Multiply, divide, remainderL2num,numnum
+, -Add, subtractL2num,numnum
+Concatenate stringsL2str,strstr
<<Shift leftL2int,intint
>>Shift right with sign extensionL2int,intint
>>>Shift right with zero extensionL2int,intint
<, <=,>, >=Compare in numeric orderL2num,numbool
<, <=,>, >=Compare in alphabetic orderL2str,strbool
instanceofTest object classL2obj,funcbool
inTest whether property existsL2str,objbool
==Test for equalityL2any,anybool
!=Test for inequalityL2any,anybool
===Test for strict equalityL2any,anybool
!==Test for strict inequalityL2any,anybool
&Compute bitwise ANDL2int,intint
^Compute bitwise XORL2int,intint
|Compute bitwise ORL2int,intint
&&Compute logical ANDL2any,anyany
||Compute logical ORL2any,anyany
?:Choose 2nd or 3rd operandR3bool,any,anyany
=Assign to a variable or propertyR2lval,anyany
*=, /=, %=, +=,Operate and assignR2lval,anyany
-=, &=, ^=, |=,    
<<=, >>=, >>>=    
,Discard 1st operand, return secondL2any,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-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.

Lvalues

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.

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

Operator Associativity

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.

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.

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.