blog bg

October 09, 2023

JavaScript: Modern Operators

Share what you learn in this blog to prepare for your interview, create your forever-free profile now, and explore how to monetize your valuable knowledge.

DESTRUTURING ASSIGNMENT(learn more)

Destructuring is an ES6 feature and it's basically a ways of unpacking values from and array or an object into separate variables. In other words destructuring into break complex data structure down into a smaller data structure like a variable

Destructuring Array

let's consider the following array

const arr = [1,2,3,4];

now if we wanted to retrieve each one into its own variable, we would do it like this

let a = arr[0];
let b = arr[1];
let c = arr[2];

But now with destructuring, we can actually declare all the three variables at the same time.

const [a,b,c] = arr;

Examples,

let's consider following array

const foodCategories = ['Italian', 'Pizzeria', 'Vegetarian', 
                            [apple juice', 'orange juice'] ]
  • get only the first and second category only
const [first,second] = foodCategories;
console.log(first,second);//Italian Pizzeria
  • get only the first and third category only.
//we just simply have a empty in the destructuring operator
const [first,,third] = foodCategories;
console.log(first,third);//Italian Vegetarian
  • switch the first and third category 
let [first,,third] = foodCategories;
console.log(first,third); //Italian Vegetarian
[first,third] = [third,first]
console.log(first,third); //Vegetarian Italian
  • access apple juice , orange juice and Italian
const [first, , , [aj,oj]] = foodCategories;
console.log(first,aj,oj);//Italian apple juice orange juice
  • access first element and keep other elements in an array
const [first, ...rest] = foodCategories;
console.log(rest);//[ 'Pizzeria', 'Vegetarian', [ 'apple juice', 'orange juice' ] ]

 

Destructuring Object

To destructure objects we user the curly braces. Then we have to provide the variable names that exactly match the property names that we want to retrieve from the object.

Unlike destructuring array, the order of elements does not matter and we don't need to manually skip elements.So we can simply write name

let's consider following object

const openingHours = {
  thursDay: {
    open: 12,
    close: 22,
  },
  friDay: {
    open: 11,
    close: 23,
  },
  saturDay: {
    open: 0, // Open 24 hours
    close: 24,
  },
}

 

Examples,

  • retrieve the thurdDay and friDay
const {thursDay,friDay} = openingHours
console.log(thursDay);//{open: 12, close: 22}
console.log(friDay);//{open: 11, close: 23}
  • rename the thursDay variable name to be different
const {thursDay:weekDay} = openingHours
console.log(weekDay);//{open: 12, close: 22}
  • set the default value if not present in the object
const {thursDay = {},sunDay = {}} = openingHours
console.log(sunDay);//{}
console.log(thursDay);//{open: 12, close: 22}
  • get the and time of friDay
const {friDay :{open,close}} = openingHours
console.log(open);//11
console.log(close);//23

 

 

THE SPREAD OPERATOR(...)[learn more]

it can be used when all elements from  an object or array need to be included in a new array or object or should be applies one-by-one in a function call's argument list

 

The Spread operator with Array

we can use the spread operator to basically expand an array into all its elements. Basically unpacking all the array elements at one.

lets say that we have an array, and now we want to create a new array based on this array. typically we loop over this array and create new array by pushing them one by one.

const num = [1,2,3];
const newNum = [3,4,...num];
console.log(newNum);//[3, 4, 1, 2, 3]

So basically, spread operator will take all the values out of this array and then write them individually 

for example,

const num = [1,2,3];
console.log(...num);//1 2 3
console.log(1,2,3);//1 2 3

 

So whenever we need the elements of an array individually, then we can use the spread operator,

  • to copy an array
const num = [1,2,3];
const newNum = [...num]//[1,2,3]
  • to join two arrays
const num1 = [1,2,3];
const num2 = [4,5,6];
const newNum = [...num1,...num2]
console.log(newNum);// [1, 2, 3, 4, 5, 6]

NOTE: we can use spread operators on iterables like arrays, strings, maps, sets NOT objects


The Spread operator with String

for example, I have string called "football" and then i want to create an array which contains all the individual letters with some additional letters

const str = "football";
const letters = [...str,"i","g"];
console.log(letters);// ['f', 'o', 'o', 't', 'b', 'a', 'l', 'l', 'i', 'g']

 

The Spread operator with Object

Since we are able to do shallow copies of arrays, using the spread operator, we can do the same with objects. 

const time = {
  openTime:11,
  closeTime:12
}
const newTime = {...time};
console.log(newTime);//{openTime: 11, closeTime: 12}

 

REST PATTERN AND PARAMETERS[learn more]

Rest pattern and also rest parameters look exactly like the spread operator. So it has the same syntax with the three dots but it actually does the opposite of the spread operator. Rest pattern uses the exact same syntax however, to collect multiple elements and condense then into an array. So that's really the  opposite of spread. The spread operator is to unpack an array while rest is to pack elements into an array.

 

Rest With Array

//SPREAD, because on RIGHT side of  = 
const arr = [1,2,...[3,4]];
console.log(arr);

//REST, because its on the left hand side of the = 
const [a,b, ...others] = arr;
console.log(others);//[3, 4]

Rest With Object

const openingHours = {
  thursDay: {
    open: 12,
    close: 22,
  },
  friDay: {
    open: 11,
    close: 23,
  },
  saturDay: {
    open: 0, // Open 24 hours
    close: 24,
  },
}

//Objects
const {saturDay, ...weekDays} = openingHours;
console.log(weekDays);//{thursDay: {...}, friDay: {...}}

 

Rest With Functions

//functions
const add = (...numbers) => {
  console.log(numbers);//[4, 5, 6, 7]
}
add(4,5,6,7);

 

TEMPLATE LITERALS(learn more)

consider following variables,
const firstName = "John";
const lastName = "ABraham";
const birthYear = 1991;
const currentYear = 2023;

Generally to contaminate strings, we can use plus(+) signs. for example,

const personDetails = "My Name is "+ firstName + " "+lastName+", a "+
                        (currentYear - birthYear)+ " years old"
console.log(personDetails);//My Name is John ABraham, a 32 years old

In ES6, a much better tool is introduced to handle this kind of complex string called Template literals/strings. it uses backtick(`) rather than quotes to define string. So with Template literals, we can write above string in normal way and then basically insert the variables directly into the string and then they will simply be replaced. for example,

const personDetails = `My Name is ${firstName} ${lastName}, 
                        a ${(currentYear - birthYear)} years old`;
console.log(personDetails);//My Name is John ABraham, a 32 years old


 

SHORT CIRCUITING (&& AND ||)

Generally, we use the logical operators only to combine Boolean values, but we can do  a lot more with && and || operators.

OR(||) operator.

console.log(5 || 'str'); //5

As you can see that result is 5 and meaning that, the results of the OR operator does not always have to be a Boolean. So in  fact, here we used two values that are not Booleans, And it then returned a value that was not a Boolean this is called Short Circuiting, meaning that if the first value is a truthy value then  it will immediately return that first value. in the OR Operator, if the first operand is truthy value then the other operand will not be evaluated. So lets do some more examples

console.log("" || 35); //35
console.log(true || 35); //true
console.log(undefined || 35); //35
console.log(null || 35); //35
console.log(undefined || null); //null - undefined is a falsy value
console.log(undefined || 0 || "" || "name"); //name

 

AND(&&) operator

console.log(0 && 35); //0
console.log(1 && 35); //35

the AND operator short circuits, when the first value is falsy, then immediately returns that falsy value without even evaluating the second operand. So, that's exactly the opposite of what happens with the OR operator. Let's do some examples,

console.log(1 && 35); //35
console.log(true && 35); //35
console.log(undefined && 35); //undefined
console.log(null && 35); //null
console.log(undefined && null); //undefined
console.log(undefined && 0 && "" && "name"); //undefined
console.log("name" && 1 && null && "i am here"); //null

In Short, OR operator will return the first truthy value of all the operands or simply the last value if of them are falsy. On the other hand, the AND operator will retrun the first falsy value or the last value if all of them are truthy.

 

THE NULLISH COALESCING OPERATOR(??)[learn more]

let guests = 0;
console.log(guests || 25);//25
console.log(guests ?? 25);//0

The nullish values are null and undefined it does not includes a zero or the empty string.So basically, for nullish coalescing operator, it is as if the zero and the empty string were not falsy values and were instead truthy values as well.


TENARY OPERATOR(learn more)

Generally, it is being considered as short form of if/else statement. This operator takes three oprands which are a condition that 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 false. 

for example,

//Regular IF/ELSE statement
let isNum = false;
if(typeof 25 === "number"){
  isNum = true;
}
console.log(isNum);//true

//TENARY OPERATOR
let checkNumber = (typeof 25 === "number") ? true : false;
console.log(checkNumber);//true


 OPTIONAL CHAINING(?.)[learn more]

lets start with an example,

let person = {
  name:"John",
  age:25
}
console.log(person.name);//John
console.log(person.job);//undefined
console.log(person.job.title);//it will throw an error 

As you can see, when we try to access job, it returns undefined because, this property doesn't exist. So if we try to access the title from job, it will throw an error as we try to access title from job which doesn't not exists in person object because person.job is undefined and undefined.title is really an error. So in order to avoid this error, first we will have to check if this property exists. To do that generally use use logical operator as shown below,

let jobTitle = "unknown";
if(person.job && person.job.tite){
  jobTitle = person.job.tite
}
console.log(jobTitle);//unknown

with the help of logical operator we got rid of error. however, this make our code more messy and a little bit more unreadable. To solve this issue, a new feature is introduced which is called optional chaining, with this feature, if a certain property does not exists, then undefined is returned immediately and so that will then avoid that find of error we show earlier.

for example,

console.log(person?.job?.title);//undefined-- it will not throw an error
let jobTitle = person?.job?.title ?? "unknown";
console.log(jobTitle);//unknown

So only if the property that is before this question mark, which means if job exists then this title property will be read from here, but if not, then immediately undefined is returned.

 

LOGICAL ASSIGNMENT OPERATORS

Logical OR Assignment(||=)[learn more]

Generally with OR operator, if the first value is truthy then will immediately be returned and the second value will not even be evaluated.

for example,

const person = {
  name:"john",
  job:""
}

person.job = person.job || "developer"
console.log(person.job); //developer
With Logical OR Assignment operator, assign a variable to a variable if that variable is currently falsy. for example,
 
person.job ||= "developer"
console.log(person.job); //developer
As you can see, because person.job is currently empty, so it will be assigned the value "developer". Basically, it evaluate the the right operand and assign to the left operand, if the left operand is falsy


 

Nullish Coalescing Assignment(??=)[learn more]

consider following example,

const person = {
  name:"john",
  job:"",
  followers:0
}
person.followers||= 30
console.log(person.followers); //30

with logical OR operator zero is actually a falsy value. So, person.followers is actually a falsy value and therefore, it will then be assigned to the value of 30. However, fortunately we can solve this issue with the logical nullish assignment operator because nullish assignment consider only null and undefined as falsy value

for example,

const person = {
  name:"john",
  job:"",
  followers:0
}
person.followers ??= 30
console.log(person.followers); //0
now person.followers is back to zero.


 Logical AND Assignment(&&=)[learn more]

this operator only evaluates the right operand and assign to the left if the left operand is truthy. for example,

const person = {
  name:"john",
  job:"",
  followers:5
}
person.followers &&= 30
console.log(person.followers); //30


 

ENHANCED OBJECT LITERALS

Object literals make it easy to quickly create objects with properties inside the curly braces. Now ES6 introduced three ways, which make it easier to write object literals.

 

Shorthand for initializing Properties

const person = {
  name:"John",
  age:25,
  hobbies:['music','movies','sports']
}

const fullName = "John Abraham"
const age = 25
const hobbies = ['music','movies','sports']

const newPerson = {
  fullName,
  age,
  hobbies
}

In above example, object newPerson is created using object literals. Much more easier to write and read. What happens here is that it check if the property key has a corresponding variable name and assigns the value of that variable to the property. if any variable has not defined with same name as the property key defined, it will throw an error


Shorthand for writing Methods

lets consider following example,

const newPerson = {
  fullName,
  age,
  hobbies,
  bornYear:function(){
    return 2023 - this.age
  }
}

if you look at the bornYear property, we need to specify function keyword to define object method. However, we no longer need to do that, so this new feature, we don't need to write function keyword to write object method like shown below

const newPerson = {
  fullName,
  age,
  hobbies,
  bornYear(){
    return 2023 - this.age
  }
}

 

Computed Properties

With this new  feature we can now actually compute property names instead of having to write them out manually and literally. we already know that there are two ways to specify a key when accessing an object property which are dot notation and bracket notation. The bracket notation allows us to access a property using expressions. Computed property names allow us to write an expression wrapped in square brackets instead of the regular property name. 

for example,

let key = "fullName";
const person = {
  [key]:"John"
}
console.log(person.fullName)//John

 

LOOPING ARRAYS

A new way of looping over arrays, which was introduced in ES6 called for-of loop.

for example,

const menu = ['Pizza', 'Coffee', 'Garlic Bread', 'Cake'];

for(const menuItem of menu){
  console.log(menuItem);
}
//output
John
Pizza
Coffee
Garlic Bread
Cake

So this loop will automatically loop over the entire array and in each iteration, it will give us access to the current array element. However, we will not be able to use the continue or break keywords.

 what if we wanted the current index and not just the current element. we can access them like shown below

for(const [index,menuItem] of menu.entries()){
  console.log(menuItem+" => "+index);
}
//output
Pizza => 0
Coffee => 1
Garlic Bread => 2
Cake => 3


 

LOOPING OBJECTS

  • If we want to loop over property names only,
for(const key of Object.keys(person)){
  console.log(key);
}

//output
name
age

Object.keys() returns the array of a given object's own string-keyed property names

  • if we want to loop over the property values only
for(const key of Object.values(person)){
  console.log(key);
}

//output
John
25

Object.values() returns the array of a given object's own string-keyed property values

  • if we want to loop over the entire object, meaning that name plus values together
for(const [key,value] of Object.entries(person)){
  console.log(`${key} => ${value}`);
}

//output
name => John
age => 25

Object.entries() returns the array of a given object's own string-keyed property key-value pairs

Next Article: JavaScript: Modern Operators - Summary with Examples

181 views

Please Login to create a Question