objects

February 25, 2023 - Reading time: 8 minutes

Let's continue our exploration of data sets in JavaScript by having a look at the objects!

Store

An object is also a collection of data but in a structured way as it's stored by pairs of property (or key) / value. For instance:

const BOOK = {
title: "The Lord of the Rings",
  "volumes": 3,
"main characters": ["Frodo", "Aragorn"],
9: ["Fellows", "Nazgul"]
};

Notes:

  • properties can be strings or numbers. Here's their syntax:
    • single word (title, volumes): quotes can be omitted (JavaScript will automatically typecast them as strings if the object has any non-string properties)
    • several words ("main characters"): quotes must be added
    • numbers (9): just type the number
  • as values, an object can contain strings, numbers, booleans, arrays, functions, and objects.

Access

Via dot or bracket notation

To access the propertie's value, you can either use the dot or the bracket notation:

const TITLE = BOOK.title;
const VOLUMES = BOOK["volumes"];
const MAIN_CHARACTERS = BOOK["main characters"];
const NINE = BOOK[9]

You can use the dot notation if your property in a string of a single word. Otherwise, user the bracket notation with quotes for strings and without for numbers.

Tip: not sure a property exists? Use optionnal chaining (?.)! It helps prevent errors when accessing nested properties that might be null or undefined.

console.log(BOOK?.isbn);

Via a variable

Properties stored as value of a variable can also be access with the bracket notation. For instance:

const MAIN_CHARACTERS = "main characters";
let charactersList = BOOK[MAIN_CHARACTERS];
console.log(charactersList);

will print

[ 'Frodo', 'Aragorn' ]

on the console.

This can be very useful for iterating through an object's properties.

Nested objects

The same principle applies to access to sub propertie's values, just continue to filter via bracket or dot notation until you reach your destination. For instance (from FreeCodeCamp):

const ourStorage = {
"desk": {
"drawer": "stapler"
},
"cabinet": {
"top drawer": {
"folder1": "a file",
"folder2": "secrets"
},
"bottom drawer": "soda"
}
};

ourStorage.cabinet["top drawer"].folder2; // returns string "secrets"
ourStorage.desk.drawer; // returns string "stapler"

Does this property exist?

To check if the property of a given object exists or not, use the .hasOwnProperty(propname) method. It returns true or false if the property is found or not. For instance:

BOOK.hasOwnProperty("title"); 
BOOK.hasOwnProperty("author");

The first hasOwnProperty returns true, while the second returns false.

Note: always use quotes for string properties, otherwise an error is thrown.

Extract

Generate an array of all object keys

Use Object.keys() method. It takes an object as the argument and returns an array of strings representing each property in the object. The order is first all non-negative integer keys in ascending order by value, then other string keys in ascending chronological order of property creation. For instance:

Object.keys(BOOK) // returns [ '9', 'title', 'volumes', 'main characters' ]

Generate an array of all object values

Same principle. Use Object.values() method.

Object.values(BOOK) // returns [ [ 'Fellows', 'Nazgul' ], 'The Lord of the Rings', 3, [ 'Frodo', 'Aragorn' ] ]

Generate an array of all object key/value pairs

Same principle. Use Object.entries() method.

Object.entries(BOOK) //returns [ [ '9', [ 'Fellows', 'Nazgul' ] ], [ 'title', 'The Lord of the Rings' ], [ 'volumes', 3 ], [ 'main characters', [ 'Frodo', 'Aragorn' ] ] ]

Iterate through

Use a for...in statement. It looks like this:

for (let item in BOOK) {
  console.log(item);
} // logs 9, title, volumes, main characters, each value in its own line

Here, "item" is a variable we define - it could be any name. Its value will change at each iteration.

Use destructuring assignment

The example comes from FreeCodeCamp.

Consider this object:

const user = { name: 'John Doe', age: 34 };

To extract both values and assign them to variables you could use:

const { name, age } = user; 

Read it as: "create constants named "name" and "age" containing values from "name" and "age" properties in "user" object". This is a shorthand equivalent of

const name = user.name;
const age = user.age;

A console.log on name and age would return John Doe and 34, each on its own line

Manipulate

Prevent mutation

const declaration can by bypassed. To protect data from mutation, use Object.freeze() function. The argument would be the object you'd like to freeze. For instance (from FreeCodeCamp):

let obj = {
  name:"FreeCodeCamp",
  review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad";
obj.newProp = "Test";

obj.review and obj.newProp assignments will result in errors and the object wouldn't change.

Update or add a value

Proceed like any other variable; using dot or bracket notation. For instance:

BOOK["main characters"][1] = "Sam";
BOOK["main characters"][2] = "Bill";
console.log(BOOK["main characters"]);

will print

[ 'Frodo', 'Sam', 'Bill' ]

on the console.

Append a property

Proceed just like you would for updating. For instance:

BOOK.format = "";
BOOK["number of copies"] = 100;
BOOK[5] = "Hello";

BOOK object will now look like this:

{
'5': 'Hello', '9': [ 'Fellows', 'Nazgul' ], title: 'The Lord of the Rings', volumes: 3, 'main characters': [ 'Frodo', 'Aragorn' ],
format: '', 'number of copies': 100
}

Order has not much importance from an object perspective because you're not using indexes to access data. But if this is important, consider using the spread operator (I'll probably write a blog entry later on this subject). Note that number properties order themselves at the beginning of the object.

Delete a property

User the delete keyword and then target your property according to it's format. For instance:

delete BOOK.format;
delete BOOK["number of copies"];
delete BOOK[5];