What’s an object?
A object
is a compound (it can hold multiple values, as opposed to primitive) data type. The syntax can vary depending on the needs of the Programmer. Two forms I have seen are the template literal {}
curly brackets, and the constructor
function
in conjunction with the new
keyword(new Object()
).
Syntax differences aside, let’s talk terminology. We discussed variables and scope (variable availability) in this previous post. As you’ll see, objects and variables interact in unique ways to create their own scope- Object scope (an unofficial term).
Properties are object variables
That’s right! a variable that is encapsulated (defined in) an object is called a property. And Objects are essentially property
(sometimes called key
) value pairs, like so:
console.clear();
// SNOBUSN... An acronym for JS data types. Thanks Wes Bos!
let breadSymbol = Symbol(); // because symbols are unique, you have to create an instance first before assigning them as an object key (combining steps won't work), otherwise you wont be able to reference them
var baguette = {
shape: "baguette",
origin: "france",
forSale: true,
priceInUSD: 8,
location: null,
bakedBy: undefined,
ingredients: ["flour", "water", "salt", "yeast"],
[breadSymbol]: "fresh baguette",
oven: {
brand: "topChef",
bakeFrenchBread: function() {
return `oven on: baking at 500F ${this.steam === true ? "with steam" : ""}`; // this is a special keyword. It's how Objects refer to themselves.
},
steam: true,
},
shareBread: function(slicePerPerson = 1, guests = 1) {
// optional parameters using default values of 1, in case this method isn't called with any arguments
var slicesPerPerson = slicePerPerson / guests;
if ( /^\d+$/.test(slicesPerPerson) ) {
// check that the value starts and ends with one or more number(s). Call the test() method on the RegEx Object which returns true if the argument passes the RegEx, or false otherwise
console.error("you must enter numbers only!");
}
if ( !Number.isFinite(slicesPerPerson) ) {
// use the error() method on the console Object if slicesPerPerson is not a finite number
console.error("infinite number. try again with proper values");
}
else {
// call the ceil() method on the Math Object. This round up slicesPerPerson to the nearest whole number
console.log(Math.ceil(slicesPerPerson));
}
}
};
console.log(baguette.oven.bakeFrenchBread()); // calling the bakeFrenchBread() method on the nested oven object that is an object in the baguette object.
Methods are object functions
Just as propertie
s are variable
s encapsulated in Object
s, method
s are function
s that are encapsulated in Object
s. In the above baguette
object
, we saw a method in the form of shareBread()
.
This method is not accessible outside the baguette
object and throws a referenceError
if you try. Because it is a method (a function defined in an Object), you must access it through the Object it is defined in. Remember, methods are not regular functions (like the ones defined in global scope), so they require special syntax (usually dot syntax) to access them.
I say usually because the way you access data in an Object will depend on if the Object key is a string or variable. Look at this code snippet we saw previously in the baguette Object:
let breadSymbol = Symbol(); // A Symbol assigned to a global variable
var baguette = {
//... other key:value pairs ...
[breadSymbol]: "fresh baguette", // notice the use of [] square brackets.
};
Because the breadSymbol
key is a variable, we must wrap it in []
square brackets. If we didn’t, the key would just be like any other old Object property, instead of being a unique Symbol
(a type of unique ID). If that confused you, try removing the []
square brackets from the property to see what I mean.
Dot VS bracket syntax
In the code snippet above, We must use []
square brackets here because the key is a variable name. The same rule applies if the key is a string
var sheriffDerek = {
name: "Derek",
userName: "SheriffDerek",
webLanguages: ["HTML", "CSS", "PHP", "JS"],
skills: ["Programming", "product design"],
["favorite drink"]: "IPA", // notice the use of [] square brackets. Required for string keys.
cool: true,
};
How would we access the “favorite drink” key in the sheriffDerek
Object? The same way we accessed Object keys that are variables: []
bracket syntax.
var sheriffDerek = {
name: "Derek",
userName: "SheriffDerek",
webLanguages: ["HTML", "CSS", "PHP", "JS"],
skills: ["Programming", "product design"],
["favorite drink"]: "IPA", // notice the use of [] square brackets. Required for string keys.
cool: true,
};
console.log(`${sheriffDerek.name} likes to drink ${sheriffDerek["favorite drink"]}`); // string interpolation with Object properties. Notice the square bracket syntax
Looping over Object Data
Now that we know who to manually access data in Objects, let’s discuss looping over Objects.
For/in
A for/in
loop is similar to a standard old for
loop but with shorter syntax. It loops over enumerable property names of an object. I had no idea what enumerable properties even were, so I consulted Mozilla Developer Network (MDN) According to MDN,
Enumerable properties are those properties whose internal enumerable flag is set to true, which is the default for properties created via simple assignment or via a property initializer. Most iteration means (such as
for...in
loops andObject.keys
) only visit enumerable keys.
In the case of our sheriffDerek
object, the data is initialized as an Object property, right? So in theory, a for/in
can be used to loop over the data. Below I am looping over an Object, assigning a variable to the current key, then using console.log(variableName)
to view the variable.
for ( let derekInfo in sheriffDerek ) {
console.log(derekInfo);
}
You can also use it for arrays, like I did below. In the case of arrays, the variable represents the current array
index, I can combine it with bracket syntax to find the number as well as current index.
var nums = [43, 65, 32];
for ( let num in nums ) {
console.log(`the number is ${nums[num]} the current index is ${num}`);
}
For/of
A for/of
loop is best used to loop over an array
, map
, set
, string,
or any other object
that has defined iteration behavior (maybe I named all of them?) In order for an object
to be iterable, it must implement the iterator
method.
When looping an array with for/of
, it iterates over the elements. For strings, it iterates over the individual character(s). For maps and sets, it iterates over their values. You can read more about for/of
in the resources section.
In the following code snippet, I use for/of
to loop over an array of numbers:
var nums = [43, 65, 32];
for ( let num of nums ) {
console.log(++num);
}
Because strings have defined iteration behavior, we can use either a for/of
or for/in
loop to access the data:
const schoolName = "Perpetual Education";
for (const letter of schoolName) {
console.log(letter);
}
In summary, in my experiecne the the use cases for for/of
and for/in
:
Use
for/of
when you want to iterate over the values of iterable objects likearray
s,string
s,map
s, orset
s. Most commonly used for arrays.Use
for/in
when you want to iterate over the enumerable properties (keys) of objects. This is typically done for working with the properties of anObject
and inspecting their structure. Most commonly used for an Object.
Object.keys()- Visualizing the keys
Often enough you may just want to view the keys of the Object. That’s easy enough with Object.keys()
. This method returns the Object keys as an array:
console.log( Object.keys(SheriffDerek) ); // ["name", "userName", "webLanguages", "skills", "favorite drink", "cool"]
Object.entries()- visualizing the Object key:value pairs
Similar to Object.keys()
, this method also returns an array
. But this time the array
consists of an array
of the key:value pairs in the Object. SheriffDerek is super cool and all, but let’s get back to the baguette object from earlier):
var baguette = {
shape: "baguette",
origin: "france",
forSale: true,
//...rest of baguette object...
}
console.log( Object.entries(baguette) );
/* logs to the console
[
["name", "baguette"],
["shape", "elongated"],
["origin", "france"],
["forSale", true],
//...rest of baguette object key:value pairs...
]
*/
Object.values()
This method returns an array of a given Object’s own enumerable values
var baguette = {
shape: "baguette",
origin: "france",
forSale: true,
//...rest of baguette object...
}
console.log(Object.values(baguette));
/* logs to the console
["baguette", "elongated", "france", true, 8, null, undefined,
["flour", "water", "salt", "yeast"],
//...rest of baguette object keys...
*/
What other ways can we loop over an object? let me know in the comments (along with if anything in this article was unclear). Thanks for reading.
Resources
Code
Coming soon… Any ideas?