JavaScript Operators


Ternary Operator

The ternary operator (sometime called conditional operator) is one of the most underused features of JavaScript, mainly due to a lot of people find it confusing on first glance.

Why

Practically everyone uses conditional formatting:

if(condition) {
  `do something`
} else {
  `do something else`
}

How

Although simple enough, one has to type quite a few extra characters. Here is the same logic using the ternary operator:

condition ? `do something` : `do something else`

If `condition` is "truthy", the first instruction is executed, otherwise the second.

Practical examples

Assign a value based on a condition (the ternary operator returns a value):

let colour = width > 100 ? "red" : "blue";

Change an element class list based on state:

var el = document.getElementById("loginButton");
loginInProgress ? el.classList.add("disabled") : el.classList.remove("disabled");

The ternary operator can be a great tool for our JavaScript projects. In most cases, it can be a simple replacement for `if...else` but have in mind this simple but critical difference: the ternary operator is an expression that returns a value whilst `if...else` doesn't.


Spread Operator

ES6 version of JavaScript introduced a lot of great improvements, and amongst them was the spread operator. It's syntax is slighly unusual: three dots followed by a name of an iterable variable.

Its purpose is simple - to expand the said iterable varable, in place, where a list of values is expected. Let's see an example - given the 2 arrays of colours below:

let colours = ['red', 'blue', 'green'];
let pastels = ['pink', 'lavender', 'peach'];

When we try to append `pastels` to `colours` using `push`:

colours.push(pastels);

we get a slighly unexpected result:

console.log(colours); 
Array(4) [ "red", "blue", "green", (3) […] ]

The `pastels` array is added as the fourth element - that's because `push` simply appends the parameter given.

Spread operator to the rescue

To get the expected behaviour, we'll have to use the spread operator when passing `pastels` to `push`:

colours.push(...pastels);
console.log(colours); 
Array(6) [ "red", "blue", "green", "pink", "lavender", "peach" ]

In our case, the spread operator is equivalent to pushing individual elements:

colours.push(pastels[0], pastels[1], pastels[2]);

What if we want to create a new variable that holds both arrays? That's simple enough:

let colours = ['red', 'blue', 'green'];
let pastels = ['pink', 'lavender', 'peach'];
let allColours = [ ...colours, ...pastels ];
console.log(colours); 
Array(6) [ "red", "blue", "green", "pink", "lavender", "peach" ]

Object copy

Another common place where the spread operator can be useful is for when making copies of objects.

Simply assigning an object value to another variable will reference to the same object:

let colour = { name: 'blue', score: 42};
let anotherColour = colour;
anotherColour.name = 'red';
console.log(colour.name); 
red

To create a copy:

let colour = { name: 'blue', score: 42};
let anotherColour = { ...colour };
anotherColour.name = 'red';
console.log(colour.name);
blue

Combine objects

Just like with arrays, the spread operators can be used to "combine" the properties of 2 objects:

let colour = { name: 'blue', score: 42};
let apiColour = { id: 25, isActive: true};
let fullColour = { ...apiColour, ...colour };
console.log(fullColour);
Object { id: 25, isActive: true, name: "blue", score: 42 }

Destructuring

Destructuring is the process of unpacking data from arrays or objects, into distinct variables.

Destructuring from arrays

Given an array, we can "extract" some of its values:

let colours = ['red', 'blue', 'green'];
let [colour1, colour2] = colours;
console.log(colour1);
red
console.log(colour2);
blue

If not enough values are present, the destination is `undefined`:

let colours = ['red', 'blue', 'green'];
let [colour1, colour2, colour3, colour4] = colours;
console.log(colour4);
undefined

However, default values can be provides:

let colours = ['red', 'blue', 'green'];
let [colour1, colour2, colour3, colour4 = 'yellow'] = colours;
console.log(colour4);
yellow

It is also possible to ignore certain values when required - notice the extra comma between `colour1` and `colour2` in the example below:

let colours = ['red', 'blue', 'green'];
let [colour1, , colour2] = colours;
console.log(colour2);
green

Destructuring assignment

This is a slight various of the previous scenario.
Sometime we need to assign values to multiple variable at the same time and destructuring makes is simpler and visually more appealing:

let colour, score;
[colour, score] = ['blue', 42];

Destructuring from objects

This will feel very similar to the destructuring from arrays - however, the names of the variables to destructure to must match the name of the object properties:

let colour = { name: 'blue', score: 42};
let {name, score} = colour;
console.log(name);
blue
console.log(score);
42

To unpack to different variable names, we need to specify both them alongside the object properties:

let colour = { name: 'blue', score: 42};
let {name: colourName, score: colourScore} = colour;
console.log(colourName);
blue
console.log(colourScore);
42

And, just like before, we can speficy default values:

let colour = { name: 'blue', score: 42};
let {id: colourId = 1, name: colourName, score: colourScore} = colour;
console.log(colourId);
1

Reading List