more of the same….
Spread Operator
The spread operator allows you to take out all of the values of an array as individual values. This is useful if you want to add values from one array into another.
For example, if you wanted to add values from one array into another, you could do it manually….
const myArray = [5,6,7,8];const newArray = [1,2,3,4, myArray[0], myArray[1], myArray[2], myArray[3]];console.log(newArray);
which would result in this…
(8) [1, 2, 3, 4, 5, 6, 7, 8]
but with the spread operator, you could simply do this….
const myArray = [5,6,7,8];const newArray = [1,2,3,4, ...myArray];console.log(newArray);
which gives the same result!
Remember, we cannot just add the ‘myArray’ array here without the spread operator, or else we’d just have a nested array inside an array….
const myArray = [5,6,7,8];const newArray = [1,2,3,4, myArray];console.log(newArray);
which would actually result in this…
(5) [1, 2, 3, 4, Array(4)]
If you want to display the values of an array individually, then you can also use the spread operator….
const myArray = [5,6,7,8];const newArray = [1,2,3,4, ...myArray];console.log(...newArray);
which results in
1 2 3 4 5 6 7 8
You can also use the spread operator to make copies of arrays…
const myArray = [5,6,7,8];const newArray = [...myArray];
or you could merge arrays together…
const arrayOne = [1,2,3,4];
const arrayTwo = [5,6,7,8];const mergedArray = [...arrayOne, ...arrayTwo];
console.log(mergedArray);
You could even pull apart a string with the spread operator, so that individual letters of the string act as individual values of an array!
const word = "JavaScript";
const wordArray = [...word];
console.log(wordArray);
which returns…
(10) ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
spread operator with objects
just like with arrays, you can make copies of objects with the spread operator…
const myNumberObject = {
one: "monday",
two: "tuesday",
three: "wednesday"
}const copyObject = {...myNumberObject};
console.log(copyObject);
Rest Operator
the rest operator does the opposite of a spread operator. It packs values into an array or object!
Even though it looks similar to the spread operator, the key difference is that the rest operator is always on the LEFT side of the assignment operator (the =) whereas the spread operator is always on the RIGHT side of the assignment operator
REST operator
[…something] = something
SPREAD operator
something = […something]
So for example:
const a = 1;
const b = 2;
const c = 3;
const d = 4;const [...newArray] = [a,b,c,d];
console.log(newArray);
so we’ve basically taken all the individual variables, and assigned them to an array ‘newArray’.
which is a bit like doing this….
const a = 1;
const b = 2;
const c = 3;
const d = 4;const newArray = [];
newArray[0] = a;
newArray[1] = b;
newArray[2] = c;
newArray[3] = d;
console.log(newArray);
We can also use the spread operator with objects….
const a = 1;
const b = 2;
const c = 3;
const d = 4;
const {...newObject} = {a,b,c,d};
console.log(newObject);
which creates a single object with four key pairs.
{a: 1, b: 2, c: 3, d: 4}
a:1
b:2
c:3
d:4
We can also use the rest operator as a parameter inside a function, which means we don’t need to specify an exact number of parameters. This is another one that’s difficult to explain, so easier to provide an example.
// basic function to add two numbers together
function numberAdd (a, b) {
return a + b;
}
console.log(numberAdd(2,7));
In the function code example above, we’d need to pass in two values when we call the function….if we tried putting in three numbers, the function would ignore the third value.
// basic function to add two numbers together
function numberAdd (a, b) {
return a + b;
}
console.log(numberAdd(2,7,8));
With the rest operator, we could approach this in a different way, so that it didn’t matter how many values we put in….
// add any amount of number into the function
function numberAdd (...numbers) {
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum;
}console.log(numberAdd(2,7,8,12,14,22));
This might seem confusing at first, but basically the …numbers parameter has taken all of the arguments when calling the numberAdd function (which in this case was 2,7,8,12,14,22) and basically created an array of those numbers, so that effectively:
numbers[0] === 2
numbers[1] === 7
numbers[2] === 8
numbers[3] === 12
numbers[4] === 14
numbers[5] === 22 numbers.length === 6
so now the for loop in the function is starting with a variable called ‘sum’ which has a value of 0. The loop runs and adds the value of numbers[0] to sum, which is 0 + 2
i is then incremented to 1, and the loop runs again, adding numbers[1] to sum, which is 2 +7
this keeps going until it reaches numbers.length (which in this case is 6) and then stops, so basically, the last loop is when i = 5
So basically the use of this rest operator in the function, has allowed us to type in any amount of arguments to be added up!
You could even mix the spread operator with the rest operator here….
const numberArray = [2,5,12,33,42,54,23,23];// add any amount of number into the function
function numberAdd (...numbers) {
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum;
}// pass in numbers to be summed with the spread operator!
console.log(numberAdd(...numberArray));
Short Circuiting with && and ||
When you compare two values with the || operator, then Javascript will not evaluate the second value, if the first value was a “truthy” value.
console.log(3 || 6);
this will return a 3
However if the first value is a “falsey” value, then it will return the second value, regardless of whether the second value is “truthy” or “falsey”….
console.log(0 || 6);
console.log(null || false);
console.log(false || undefined);
these would return:
6
false
undefined
In a chain of or operators, the first “truthy” value will be shown…
console.log(false || undefined || "Hello" || 6 || true || null);
this would return “Hello”
Now at first glance, it might seem difficult to see why this would be useful knowledge, but we can use this to apply default values to a variable if the variable doesn’t exist or has no value.
For example:
let bobsAge;
let checkBobsAge = bobsAge || "request age";
console.log(checkBobsAge);
so basically, if we don’t have bob’s age stored, then we can return a message to say that we need to check it.
The other way, would be to use an if else statement, or a ternary operator, but using or || is still much quicker than doing this…
let bobsAge = 2;
let checkBobsAge;
if (!bobsAge > 0 ? checkBobsAge = "request age" : checkBobsAge = bobsAge);
console.log(checkBobsAge);
short circuiting with the && operator works in the exact opposite way, whereby it will return the final “truthy” value, as long as ALL values are “truthy” values.
If ANY of the values are “falsy”, then it will return the first “falsy” value, as it no longer needs to continue with the evaluation.
For example:
console.log(3 && 0 && 6);
console.log(null && false);
console.log("truthy" && false && undefined);
console.log("hello" && 5 && true && "goodbye");
will return the following:
0
null
false
goodbye
so an example of how you could use this would be as follows:
let hasTicket = true;
let isOverEighteen = false;
let onTime = true;
let isAdmitted = hasTicket && isOverEighteen && onTime;
console.log(isAdmitted);
if any of the first three variables are not true (or “truthy” values) then the result will be false.
The “nullish coalescing” operator
this has a very bizarre name, but I guess that will make it memorable in a strange way.
It is written as ??
It works similar to the || operator, however if the value is “nullish” (and NOT “falsey”!) which is basically the “null” and the “undefined” values
?? is for "nullish" values which are "null" and "undefined"
It actually treats 0 and “ “ (empty string) and ‘false’ as though they are “truthy” values.
So, unlike the || operator, when you compare two values and Javascript will not evaluate the second value, if the first value was a “truthy” value, the “nullish coalescing” operator will see the 0 and “ “ empty string and ‘false’ as “truthy” values, and will show the first “truthy” value it evaluates. If it cannot find ANY “truthy” value, then it will return the final value.
Here is an example of using it….
console.log(0 ?? 6);
console.log(null ?? false);
console.log(false ?? "" ?? undefined);
console.log(undefined ?? "" ?? 0);
console.log("" ?? null ?? undefined);
console.log(null ?? undefined);
This would produce the following results…
0
false
false
""
""
undefined
Use of this operator would be useful if you actually wanted to track ‘false’ or 0 as a valid value.
Logical assignment operators
you can also use shorthand operators to check if a value is truthy, and if not, assign a value…. for example:
const restuarant = {
name: "Pizza Perfect",
numberOfStaff: 18,
menuOptions: 38,
open: true
}restuarant.yearOpened ||= 1995;
console.log(restuarant);
So basically this object didn’t have a “yearOpened” key value pair, so it added one based on restuarant.yearOpened being a “falsey” value, so moved on to the next evaluation.
You can do a similar thing with the “nullish coalescing” operator…
const restuarant = {
name: "Pizza Perfect",
numberOfStaff: 18,
menuOptions: 38,
open: true,
accidentsRecorded: 0
}
restuarant.accidentsRecorded ??= "not recorded";
console.log(restuarant);
In this case, the value of accidentsRecorded will be 0 (as opposed to “not recorded”) because the nullish coalescing operator treats 0 as a “truthy” value.