For ‘of’ loops
different to regular for loops…
We can take an array and then loop through it…
const menu = [
"pizza",
"steak",
"spaghetti",
"salad",
"meatballs",
"chicken",
"fish"
];for (let item of menu) {
console.log(item);
}
which prints the following to the console:
pizza
steak
spaghetti
salad
meatballs
chicken
fish
This is looping through the values themselves, but we can now use the .entries method, to actually see the array values and the index value….
const menu = [
"pizza",
"steak",
"spaghetti",
"salad",
"meatballs",
"chicken",
"fish"
];for (let item of menu.entries()) {
console.log(item);
}
returns…
(2) [0, 'pizza']
(2) [1, 'steak']
(2) [2, 'spaghetti']
(2) [3, 'salad']
(2) [4, 'meatballs']
(2) [5, 'chicken']
(2) [6, 'fish']
So we can see that “chicken” is the sixth entry, with an index of 5.
we could even de-structure the item into two parts here….
const menu = [
"pizza",
"steak",
"spaghetti",
"salad",
"meatballs",
"chicken",
"fish"
];for (let [number, food] of menu.entries()) {
console.log(number,food);
}
which returns…
0 'pizza'
1 'steak'
2 'spaghetti'
3 'salad'
4 'meatballs'
5 'chicken'
6 'fish'
so basically for each loop, we print to the console, the index value, and then the value itself.
We could even do something fancy here such as this…
const menu = [
"pizza",
"steak",
"spaghetti",
"salad",
"meatballs",
"chicken",
"fish"
];for (let [number, food] of menu.entries()) {
console.log(`menu number ${number+1} : ${food}`);
One big advantage of the ‘for of’ loop, is that no counter is needed.
Enhance Object Literals
A couple of benefits of object literals…
Firstly, if you want to reference an object inside another object you could do the following:
const objectTwo = {
carFour: "ford",
carFive: "citroen"
};const objectOne = {
carOne: "jaguar",
carTwo: "mercedes",
carThree: "ferrari",
objectTwo
};console.log(objectOne.objectTwo);
Another advantage is that we can compute the ‘keys’ in key value pairs within objects. For example..
const weekdays = ["mon", "tue", "wed", "thur", "fri"];const newObject = {
[weekdays[0]]: "go to gym",
[weekdays[2]]: "buy shopping"
}console.log(newObject);
which would return…
{mon: 'go to gym', wed: 'buy shopping'}
Optional Chaining
Object optional chaining solves the “non-existing property” problem. Sometimes we want to return “undefined” when an object property doesn’t exist, rather than throwing an error.
For example:
let user = {}; // a user without "address" propertyconsole.log(user.address.street.name); // Error!
The old way of tackling this issue, and without producing an error, would be something like this…
let user = {};console.log(user.address && user.address.street && user.address.street.name);
With optional chaining, we can do this…
let user = {}; // user has no addressconsole.log( user?.address?.street?.name ); // undefined (no error)
If according to our code logic, the ‘user’ object MUST exist, but the address object is optional, then we should write user.address?.street, but NOT user?.address?.street
This is because ‘user’, could simply be a variable without a value, not necessarily an object, and if we had user?. then we’d get undefined, even though there is no user object at all!
For example..
let user; // not an object!console.log(user?.address?.street?.name );
This will return undefined, whereas in this case, you’d probably want an error message to appear.
let user; // not an object!console.log(user.address?.street?.name );
This WILL throw an error, which is probably what we’d want, to inform us that there’s not even an object called user, and that the ‘user object really should exist!
Don’t overuse optional chaining! Coding errors can be silenced where not appropriate, which makes code more difficult to debug.
Object.keys()
Object.keys() returns an Array Iterator object with the keys of an object:
For example, when used on an array:
const fruits = ["Banana", "Orange", "Apple", "Mango"];
const keys = Object.keys(fruits);
console.log(keys);
returns the keys (or basically the index values) as an array
['0', '1', '2', '3']
If used on an object…
const person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};
const keys = Object.keys(person);
console.log(keys);
returns the ‘keys’ as an array
['firstName', 'lastName', 'age', 'eyeColor']
Object.values()
As you’d expect, this returns an array iterator object with the values of an object.
When used on an array…
const fruits = ["Banana", "Orange", "Apple", "Mango"];
const keys = Object.values(fruits);
console.log(keys);
returns the values as an array…
['Banana', 'Orange', 'Apple', 'Mango']
and when used on an object….
const person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};
const keys = Object.values(person);
console.log(keys);
returns the values of the object….
['John', 'Doe', 50, 'blue']
Object.entries()
Object .entries() returns both the index and value for arrays, and the key and value for objects….
For example, on the array…
const fruits = ["Banana", "Orange", "Apple", "Mango"];
const keys = Object.entries(fruits);
console.log(keys);
produces an array of arrays….
[Array(2), Array(2), Array(2), Array(2)]
and with an object…
const person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};
const keys = Object.entries(person);
console.log(keys);
also creates an array of arrays!
[Array(2), Array(2), Array(2), Array(2)]