Logical Assignment Operators
Merry Christmas! I'm getting this blog post in a little under the wire. I had started a little series on ES2021 features, which includes the .replaceAll()
String Method, Private Class Methods, Private Accessors, and Promise.any()
. However, I had a little bit of a panic as I started writing Promise.any()
. I had intended on doing a larger series focusing on JavaScript Promise
s, touching on what Promise
s are, the various states of Promise
s, and their available methods. But as I faced writing about Promise.any()
with none of those other posts written, it was clear to me I finally needed to tackle the larger Promise
ecosystem in order to do the new ES2021 feature justice. Hence the series that I just wrapped, which includes Promise
, Promise.all()
, Promise.allSettled()
, Promise.any()
, Promise.race()
, Promise.reject()
, and Promise.resolve()
.
All of this is a roundabout way of saying that I'm finally wrapping up my ES2021 blog post series with this post. The only things I will not have covered are WeakRef and Finalizers. These topics are related to how the JavaScript language does garbage collection, and to be frank I think that's a topic that is well beyond my current grasp. Rather than write about something I have absolutely no reference for or thoughts about when I might use it, I'm just going to avoid it for now. Maybe I'll visit garbage collection at a future date. Wow, I'm rambling again. Okay, onto Logical Assignment Operators.
Review: Logical Operators, Nullish Coalescing Operator, and Assignment Operators
Before getting into Logical Assignment Operators, it would be useful to understand the operators that they are built on.
Logical Operators
Logical Operators are used to determine logic between variables and values. Let's say we have two variables, x = 100
and y = 25
.
The &&
operator represents "and". Let's take a look at it in practice:
const x = 100;const y = 25;
console.log(x < 150 && y > 15);// Expected result: true
The statement x < 150 && y > 15
is evaluating whether the value of x
is less than 150
and (&&
) the value of y
is greater than 15
.
The ||
operator represents "or". Here's an example:
const x = 100;const y = 25;
console.log(x === 150 || y === 15);// Expected result: false
The statement x === 150 || y === 15
is evaluating whether the value of x
is strictly equal to 150
or (||
) the value of y
is equal to 15
. In this case, neither expression evaluates to true
, so the entire statement evaluates to false
.
The last Logical Operator is the !
operator, which represents "not":
const x = 100;const y = 25;
console.log(!(x === y));// Expected result: true
The statement !(x === y)
is evaluating whether the value of x
is not (!
) equal to y
(or to be more technically correct, the opposite value of whether x
is strictly equal to y
). 100
is not equal to 25
, so this statement evaluates to true
.
Nullish Coalescing Operator
I touched on the Nullish Coalescing Operator briefly in my post undefined
vs null
. In the interest of not duplicating work, I'll just copy that content here:
The Null Coalescing Operator is represented by two question marks (??
), which separates two expressions. If the first, left hand, expression is Nullish (i.e. either undefined
or null
), then the second, right hand, expression gets returned. If the first, left hand, expression is anything other than undefined
or null
, then that is the expression that gets returned.
Here's an example:
const nullThing = null;const falsyThing = "";const string = "Here's a string";
const firstTest = nullThing ?? string;console.log(firstTest);// Expected result: "Here's a string"
const secondTest = falsyThing ?? string;console.log(secondTest);// Expected result: ""
In the case of firstTest
, the left hand expression is a null
value, so the right hand expression gets returned.
In the case of secondTest
, the left hand expression, an empty string, is a Falsy Value, but not undefined
or null
, so the Nullish Coalescing Operator returns the empty string.
Assignment Operators
The last set of operators I want to review before getting into the new stuff is Assignment Operators. Assignment Operators assign a value to its left operand based on the value of its right operand.
The =
is called the Simple Assignment Operator and is probably one of the most widely used features in the language. In most cases, it creates a name space in memory for the left operand and assigns the value of the right operand to that name space:
const person = "Joey";
There are, however, much more complicated Assignment Operators. The Addition Assignment Operator, for example (+=
), adds the value of the right operand to a variable and assigns the result to the variable. For example:
let a = 100;let b = "howdy";
console.log((a += 50)); // addition operation// Expected result: 150
console.log((b += " world")); // concatenation operation// Expected result: "howdy world"
A similar operator is the Subtraction Assignment Operator (-=
), which is less frequently used:
let a = 150;let b = "howdy world";
console.log((a -= 50)); // subtraction operation// Expected result: 100
I'm only scratching the surface of Assignment Operators here, as there are a ton of them. I'm not sure when many would be used, and diving into things like Bitwise or Left and Right Shift are not the point of this blog post. Instead, I'm here to write about Logical Assignment Operators.
Logical Assignment Operators
ES2021 introduces three new assignment operators, known as Logical Assignment Operators, to the language. These are the Logical And Assignment Operator (&&=
), the Logical Or Assignment Operator (||=
), and the Logical Nullish Operator (??=
). They combine logical (or nullish coalescing) operations with assignment operations.
Logical And Assignment Operator
The Logical And Assignment Operator (&&=
) will check whether its left operand is truthy. If so, it will assign the value of the right operand to the left operand. If the left operand is falsy, it will leave the value of the left operand as it currently is.
let a = "howdy";let b = false;
a &&= "hello";console.log(a);// Expected result: "hello";
b &&= "hello";console.log(b);// Expected result: false
Here is the old way of doing this kind of check and reassignment:
let a = "howdy";let b = false;
if (a) { a = "hello";}
if (b) { b = "hello";}
console.log(a); // "hello"console.log(b); // false
Logical Or Assignment Operator
The Logical Or Assignment Operator (||=
) does something similar, but checks whether the left operand is falsy. If so, it will assign the value of the right operand to the left operand. If the left operand is truthy, it will leave the value of the left operand as it currently is.
let a = true;let b = "";
a ||= "hello";console.log(a);// Expected result: true
b ||= "hello";console.log(b);// Expected result: "hello"
Here is the old way of doing this kind of check and reassignment:
let a = true;let b = "";
if (!a) { a = "hello";}
if (!b) { b = "hello";}
console.log(a); // trueconsole.log(b); // "hello"
Logical Nullish Assignment Operator
Where the Logical And Assignment Operator and Logical Or Assignment Operator are concerned with items that are either truthy or falsy, the Logical Nullish Assignment Operator (??=
) is concerned with whether the value it is checking is nullish, i.e. either null
or undefined
.
let a = null;let b = false;
a ??= "howdy world";console.log(a);// Expected result: "howdy world";
b ??= "howdy world";console.log(b);// Expected result: false
Here is the old way of doing this kind of check and reassignment:
let a = null;let b = false;
if (a === null || a === undefined) { a = "howdy world";}
if (b === null || b === undefined) { b = "howdy world";}
console.log(a); // "howdy world"console.log(b); // false
So there you have it, the three new Logical Assignment Operators. In all honesty, as clever as they are, I think they really reduce readability of the code. I will definitely have to look these operators up again when I run into them in the wild (or ever decide to be a hotshot and try to use them myself), but that's what this blog post is for. Oh well.