The Big 'O' of Javascript

The Big 'O' of Javascript

The Ultimate guide for Objects in Javascript

·

6 min read

Recap

JavaScript was one of the first programming languages I picked up. Being an extremely powerful and omnipresent language, JavaScript has the potential to tap into so many popular industries like Machine Learning and Data Analysis and take over other programming languages.

It's even happening now with tools like Tensorflow, JSP, etc. To all the JS/TS devs, don't worry, JS will help us in world domination! (pun intended)

Keeping aside our plan of world domination (for now) let's focus on the Big 'O' of Javascript i.e., Objects.

Objects in Javascript

Nearly everything in JavaScript is an object other than five things that are — undefined, strings, numbers, boolean, and symbols. Thus, objects penetrate almost every aspect of Javascript.

In this guide, we'll take examples of plain objects for our ease of understanding.

The CRUD of Objects

  • Creating an Object

      // Method 1 - using Object literals ( let student = {} )
      let student1 = {
        id: 1,
        name: "Utkarsh",
        age: "25",
        address: "Gurugram, Haryana (IN)",
        updateAddress: (newAddress) => {this.address = newAddress}
      };
    
      // Method 2 -  using constructor syntax
      let student20 = new Object(); // student2 = {}
      let student21 = new Object(student1);
    
      // Method 3 - using Object.create()
      //    creates a new object with specified prototype and properties of an old object.
      let student3 = Object.create(student2);
    
      // Method 4 - using Object.fromEntries()
      //    creates a new object using an interable such as a 2D array or a map.
      let student4 = Object.fromEntries([
          ['name', 'Utkarsh'],
          ['age', 23],
          ['profession', 'Utkarsh'],
      ]);
    
  • Reading an Object

    • Reading a single value

        let person = {
            name: "Utkarsh",
            age: 25,
        };
      
        console.log(person.name) // prints out "Utkarsh" (Throws error if name does not exist and strict mode is turned on)
        console.log(person['name']) // prints out "Utkarsh" (Returns undefined if name does not exist)
      
    • Reading multiple values (loops)

        let person = {
            name: "Utkarsh",
            age: 25,
            profession: "Software Engineer"
        };
      
        // Method 1 - using for in loop
        for(let key in person){
            console.log(key, " = ", person[key]); // prints - "name = Utkarsh"
        }
      
        // Method 2 - using for of loop
        for(let value of person){
            console.log(value); // prints - "Utkarsh"
        }
      
        // Method 3 - using Object.entries()
        for(const [key, value] of Object.entries(person) ){
            console.log(key, " = ", value); // prints - "name = Utkarsh"
        }
      
        // Method 4 - using Object.keys(). This method returns an array of keys
        console.log(Object.keys(person)); // prints ["name", "age", "profession"]
      
        // Method 5 - using Object.getOwnPropertyNames(). This method returns an array of keys
        console.log(Object.getOwnPropertyNames(person)); // prints ["name", "age", "profession"]
      
        // Method 6 - using Object.values(). This method returns an array of values
        console.log(Object.values(person)); // prints ["Utkarsh", 25, "Software Engineer"]
      
  • Updating an Object

    All below-given ways update the value of the key if it exists, otherwise, they create a new key with the given value.

      // Updating an object is as simple as assigning a new value to an existing key in object
      person.name = "Abhey"; // throws error if name does not exist and strict mode is turned on
      person['name'] = "Abhey";
    
      // using Object.defineProperties()
      Object.defineProperties(person, {name: "Abhey"});
    
      // using Object.defineProperties() - updates multiple properties
      Object.defineProperties(person,{
        name: "Abhey",
        age: 24,
      });
    
      // using Object.defineProperty() - update a single property at a time
      Object.defineProperties(person, "name", "Abhey");
    
      // using ES6 spread operator
      person = {...person, name: "Abhey"}
    
  • Deleting elements in an object

      delete person.name // returns true as the key-value pair will be deleted
      delete person['name'] // again returns true even 'name' key does not exist anymore
    

Since we're now done with the CRUD operations of the object. let's move to the next section.

Checking if a given key exists in an object

// Method 1 - using hasOwnProperty
console.log(person.hasOwnProperty('name')); // prints true

// Method 2 - using in operator
console.log('name' in person); // prints true

// Method 3 - manual Check
console.log(person?.name != undefined); // prints true
console.log(person['name'] != undefined); // prints true
// This method is not reliable if the name property exists and has undefined value.

// Method 4 - using Array.indexOf()
console.log(Object.keys(person).indexOf('name') !== -1); // prints true
// Here, we're first creating an array of keys and then checking if the given key exists in the array or not. Thus, this method is not recommended.

Destructuring an Object

Destructuring is an expression which allows us to access the data from objects like arrays, objects, and maps and assign it to new variables. In other words, destructuring allows us to pick specific data from an object.

Consider the following example -

let student1 = {
  id: 1,
  name: "Utkarsh",
  age: "25",
  address: "Gurugram, Haryana (IN)",
};

const { name, age } = student1;

console.log(`Name of the student is `, name);

Deep copy and shallow copy

  • Shallow Copy - A shallow copy is a copy of an object that shares the same references to the source objects from which the copy was made.

      const sourceObject = {
          name: "Utkarsh",
          age: 25,
      };
    
      // method 1 - object assignment
      const shallowCopy1 = sourceCopy;
    
      // method 2 - using Object.assign()
      const shallowCopy2 = Object.assign({}, sourceCopy);
    
      // method 3 - using Object constructor
      const shallowCOpy3 = new Object(sourceObject);
    

    Note: Changes made in one shallow copy will be reflected in all the other copies including the source object.

  • Deep Copy - A deep copy is a copy of an object that does not share the same references to the source objects from which the copy was made.

      const sourceObject = {
          name: "Utkarsh",
          age: 25,
      };
    
      // method 1 - using ES6 Spread operator
      const deepCopy1 = {... sourceObject};
    
      // method 2 - JSON.stringify() and JSON.parse() 
      const deepCopy2 = JSON.parse(JSON.stringify(sourceCopy));
    
      // method 3 - structuredClone()
      const deepCopy3 = structuredClone(sourceCopy);
      //  This method internally uses structured clone algorithm to create a deep copy of the object. More details at - https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
    

    Note: Changes made in one deep copy will not be reflected in any other copy or source object.

Circular Objects

Circular Objects are objects that contain references to each other, thus, creating a circular dependency between them. This leads to the object containing a reference to themselves infinitely.

let dog = new Object();
let person = new Object();
// Creating a circular reference
dog.owner = person;
person.pet = dog;

Output -

In older browsers, such objects caused memory leak issues. However, with improvements in the garbage collectors, we can handle such circular objects and cyclic dependencies.

How to compare two objects?

The equality == and strict equality === operators for objects work the same i.e two objects are equal only if they share the same reference to the memory.

For instance, if two variables reference the same object, they are equal:

const a = {};
const b = a;
const c = {};
console.log(b == a, b === a); // return true true
console.log(c == a, c === a); //return false false

Conclusion

In this blog, we have discussed the most commonly used methods that you can use with Objects in Javascript. If we have missed any, please comment down below in the comment section.

Happy Coding!

Did you find this article valuable?

Support Utkarsh by becoming a sponsor. Any amount is appreciated!