Operators in javascript can either be used for logical expression where you connect two or more expressions and can be a comparison expression where you compare two values.
You can also use an operator for arithmetic expressions, assignment expressions, and even more.
In this guide, we would look at some operators, I won't cover all, but would go through some of them.
Below is a table of operators by precedence. When an operator has higher precedence, it means it would be executed first in an expression with more than one operator, and when the operator has lower precedence, it won't be evaluated first if an only if other operators have higher precedence.
The following table summarizes the precedence and associativity (the order in which the operands are evaluated) of JavaScript operators, listing them in order of precedence from highest to lowest.
Left-associativity (left-to-right) means that it is processed from left to right, while right-associativity (right-to-left) means it is processed from right to left.
Where several operators appear together, they have equal precedence and are evaluated according to their associativity:
Table of operators by precedence
Precedence Type of operation Associativity Symbol/Operator 21 Grouping n/a (...) 20 Member Access left-to-right ... . ... .. Computed Member Access left-to-right ... [ ... ] .. new (with argument list) n/a new ... ( ... ) .. Function Call left-to-right ... ( ... ) .. Optional chaining left-to-right ?. 19 new(without argument list) right-to-left new ... 18 post-increment, n/a ... ++ post-decrement n/a ... -- 17 Logical Not right-to-left ! ... .. Bitwise Note ............. ~ ... .. Unary Not ............. + ... .. Unary Negation ............. - ... .. Prefix Increment ............. ++ ... .. Prefix Decrement ............. -- ... .. typeof ............. typeof ... .. void ............. void ... .. delete ............. delete ... .. await ............. await ... 16 Exponential right-to-left ... ** ... 15 Multiplication left-to-right ... * ... Division ............. ... / ... Remainder ............. ... % ... 14 Addition left-to-right ... + ... Subtraction ............. ... - ... 13 Bitwise Left Shift left-to-right ... << ... Bitwise Right Shift ............. ... >> ... Bitwise Unsigned Right Shift ............. .. >>> ... 12 Less Than left-to-right ... < ... Less Than Or Equal . ............. ... <= ... Greater Than ............. ... > ... Greater Than Or Equal ............. ... >= ... in ............. ... in ... instanceof ............. ... instanceof ... 11 Equality left-to-right ... == ... Inequality ............. ... != ... Strict Equality ............. ... === ... Strict Inequality ............. ... !== ... 10 Bitwise AND left-to-right ... & ... 9 Bitwise XOR left-to-right ... ^ ... 8 Bitwise OR left-to-right ... | ... 7 Logical AND left-to-right ... && ... 6 Logical OR left-to-right ... || ... 5 Nullish coalescing operator left-to-right ... ?? ... 4 Conditional right-to-left ... ? ... : ... 3 Assignment right-to-left ... = ... ... += ... ... -= ... ... **= ... ... *= ... ... /= ... ... %= ... ... <<= ... ... >>= ... ... >>>= ... ... &= ... ... ^= ... ... |= ... ... &&= ... . .. ||= ... ... ??= ... 2 yield right-to-left yield ... yield* yield* ... 1 Comma / Sequence left-to-right ... , ...
If several operators appear on the same line or in a group, they have equal precedence. An expression can contain several operators with equal precedence. When several such operators appear at the same level in an expression, evaluation proceeds according to the associativity of the operator, either from right to left or from left to right.
The difference in associativity comes into play when there are multiple operators of the same precedence level.
Let's see some example, suppose you have the following:
(5 + 15 * 3); // => 50
(5 + (15 * 3)); // => 50: it is going to evaluate whatever is in the parentheses first cos it has higher precedence
((5 + 10) * 3); // => 45 because the parentheses change the order, and since it has higher precedence, it would be evaluated first
Assignment operators are right-associative, so you can write:
a = b = 1; // same as writing a = (b = 1);
First, b is set to 1. Then the a is also set to 1, the return value of b = 1, aka right operand of the assignment. This is given by the associativity rule, so, you can cross check the table for reference.
Whenever you are confused about the precedence, you can always use parenthesis to force the orderliness. In short, always use parenthesis to avoid creating unwanted bugs, and it can also make your code clearer.
Operand and Result Type
As we've seen in our previous guide, an operator can typically work on values of any type, take for example, if you are doing string "5" + number 6, JavaScript would convert the operands to numbers. The value of this expression is the number 11, not the string “11”, so, in disguise, the operator expects the value to be of a specific type, so, if you have a different type that isn't supported by the operator, JavaScript would try to help you convert it into a supported type.
Equality and Inequality Operators
The equality operators can be written in two ways, the first one is the less strict equality: == and the second is the strict equality === They both 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 difference between the two is that the strict equality checks whether its two operands are identical as in both the types of data and value.
While the other which is mostly known as equality operator would only check the exactness of the value.
Inequality operators are != and !== which 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 if otherwise, while the !== operator returns false if two values are strictly equal to each other and return true otherwise.
There is one thing to point out about strict equality, look at the following expressions:
0 == -0 // => true
0 === -0 // => true
The explanation as to why it is equal is beyond the scope of this guide, but if you ever want to differentiate it, you can use the object.is method as follows:
Object.is(0,-0) // => false
Comparison Operator
Comparison operators are generally used to compare two values or operands, and thus produces an output based on the evaluation of the expression. It is that simple.
Here are some examples:
Example | Operator | Result |
$j < $k | Less Than | TRUE if $j is less than $k |
$j > $k | Greater Than | TRUE if $j is greater than $k |
$j <= $k | Less Than or Equal To | TRUE if $j is less than or equal to $k |
$j >= $k | Greater Than or Equal To | TRUE if $j is greater than or equal to $k |
Note: = is not the same as ==, the first one is for assignment, e.g assigning values to a variable, and the latter is for equality.
Note that 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:
12+ 2 // => 14: addition.
"1" + "2" // => "12": concatenation.
"1" + 2 // => "12": 2 is converted to "2".
11 < 3 // => false: numeric comparison.
"11" < "3" // => true: string comparison.
"11" < 3 // => false: numeric comparison, "11" converted to 11.
"three" < 3 // => false: numeric comparison, "three" converted to NaN.
The Conditional/Ternary Operator (?:)
The ternary operator is a conditional operator that can provide handy shortcuts when testing conditions of a value.
An expression x ? y : z evaluates to y if the value of x is true, and if false, it evaluates z. If you quickly want to grab the syntax, then you can think of it as if x is true, evaluate y, else z.
The ternary operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (?), then an expression to execute if the condition is truthy followed by a colon (:), and finally the expression to execute if the condition is falsy. This operator is frequently used as a shortcut for the if statement.
Consider the following example:
let age = 23;
let beverage = (age >= 21) ? "Beer" : "Juice";
console.log(beverage); // => "Beer
This is like saying, if age is greater than 21, then output "Beer", otherwise, "Juice".
You can also chain it together like so:
let age = 60;
let beverage = (age <= 50) ? "Beer"
: (age <= 13) ? "Water"
: (age <= 17) ? "Juice"
: "Nothing For You"
console.log(beverage); // => "Nothing For You"
Anything above 50, would default to "Nothing For You"
This is similar to if..else if...else:
let age = 40;
if (age <= 50) { beverage = "Beer" }
else if (age <= 13) { beverage = "Water" }
else if (age <= 17) { beverage = "Juice" }
else { beverage = "Nothing For You" }
console.log(beverage);
I prefer the ternary operator, but it's your choice which ever you end up using.
Nullish coalescing operator (??)
The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined and otherwise returns its left-hand side operand.
This is similar to logical OR(||) operator in that it evaluates its second operand if the first operand evaluates to null or undefined. In other words, if you use || to provide some default value to another variable $myVar, you may encounter unexpected behaviors if you consider some falsy values as usable (eg. '' or 0).
For example:
let $myVar = null ?? "A default string";
console.log($myVar); // => "A default string"
If the value of the $myVar is null, it would assign the value in the right hand("A default String"), now, consider the following example:
let $myVar;
$myVar ?? "A default string";
console.log($myVar); // => undefined
This would give you undefined because you have already declared the variable, and you are using a Nullish coalescing withouting doing a new assignment as we've done in the first example, you can use this if for example, you don't want to replace the value of the variable, something like this:
let $myVar;
$myVar ?? "A default string";
// => "A default string"
But, if you want to replace the value of the variable, make sure you are using the Nullish coalescing operator in the assignment:
let $myVar = null ?? "A default string";
console.log($myVar); // => "A default string"
A common way among programmers when assigning default value to a variable is to use the logical OR operator (||):
let myvar;
let someDummyText = myvar || 'Hello!';
Note that myvar is never assigned any value so it is still undefined. The interesting thing here is that || is a boolean logical operator, and the left hand-side (myvar) is also undefined, JavaScript would assume you are trying to use a boolean evaluation, which would then cause it not to return anything. In short, any falsy value (0, empty string(' '), NaN, null, undefined) will always return nothing in this scenario
And this may cause unexpected consequences if you consider 0, '', or NaN as valid values.
More examples:
let num = 0;
let strng = "";
let qty = num || 22;
let message = strng || "Hey!";
console.log(qty); // => 22 and not 0
console.log(message); // =>"Hey!" and not ""
The num || 22 actually means, if num variable has a false value, assign 22 to qty. Since it see num has a value of "0" it says, oh, you are using a boolean logical OR, and I might as well convert 0 to false, this would act the same for all falsy values, which is why the variable message was passed "Hey!" even if we have thought it shouldn't.
The nullish coalescing operator avoids this pitfall by only returning the second operand when the first one evaluates to either null or undefined (but no other falsy values):
let mystng = ''; // An empty string (which is also a falsy value)
let notfalsy = mystng || 'Hey';
let preservingFalsy = mystng ?? 'Hi brah';
console.log(notFalsy); // => Hello world
console.log(preservingFalsy); // => '' (as mystng is neither undefined nor null)
The ?? operator is similar to the && and || operators but does not have higher precedence or lower precedence than they do. If you use it in an expression with either of those operators, you must use explicit parentheses to specify which operation you want to perform first:
(x ?? y) || z // => ?? first, then ||
x ?? (y || z) // => || first, then ??
x ?? y || z // => SyntaxError: parentheses are required
This is a new operator and it is defined bt ES2020, so, you might want to use a polyfill when using this.
Let's round up this guide with...
The Comma Operator (,)
The comma operator is a binary operator whose operands may be of any type. It evaluates its left operand, evaluates its right operand, and then returns the value of the right operand.
This lets you create a compound expression in which multiple expressions are evaluated, with the compound expression's final value being the value of the rightmost of its member expressions.
You will mostly use this in a for loop.
For example:
a=3, b=5, c=8;
This gives you 8. I no it doesn't make much sense now, but I'll cover it more in depth coming section.