DEV Community

shunku
shunku

Posted on

Chapter 5: Advanced JavaScript Concepts

Prototypes and Inheritance

JavaScript is often described as a prototype-based language, which means that it doesn't have classical inheritance based on classes as seen in other languages like Java or C++. Instead, JavaScript uses prototypes to achieve object-oriented inheritance.

Each object in JavaScript has a private property called a prototype, which points to another object. When a property is accessed on an object, and the object does not have that property, JavaScript will traverse the prototype chain to find the property on one of the prototypes.

Here's an example of prototypes in action:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.getFullName = function() {
  return this.firstName + " " + this.lastName;
}

let person = new Person("John", "Doe");
console.log(person.getFullName()); // Outputs: "John Doe"
Enter fullscreen mode Exit fullscreen mode

In this example, the getFullName method is added to the prototype of the Person constructor function. All instances of Person can now use this method.

Asynchronous JavaScript (Promises, async/await)

JavaScript is single-threaded, but it has features that allow it to handle tasks that take a long time to complete, such as fetching data from a server, without blocking the rest of the code from executing. This is achieved with async functions and the Promise object.

A Promise represents a value that is unknown now that may become known in the future. Promises can be in one of three states: pending, fulfilled, or rejected.

let promise = new Promise(function(resolve, reject) {
  // some code

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  } else {
    reject(Error("It broke"));
  }
});

// We can chain a .then() call to our promise to specify what should happen when the promise is resolved:
promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});
Enter fullscreen mode Exit fullscreen mode

async and await are extensions of promises, and they allow you to write promise-based code as if it were synchronous.

async function getFullName() {
  try {
    let response = await fetch('/api/person');
    let person = await response.json();
    console.log(person.firstName + " " + person.lastName);
  } catch (error) {
    console.error('Error:', error);
  }
}

getFullName();
Enter fullscreen mode Exit fullscreen mode

Error Handling and Debugging

JavaScript provides several mechanisms for handling errors and debugging your code.

One such mechanism is the try...catch statement, which is used to handle exceptions (unusual or erroneous situations) that can be thrown by your program.

try {
  // Code that may throw an exception
  throw new Error('Oops!');
} catch (error) {
  // Handle the error
  console.error(error.message); // Outputs: "Oops!"
}
Enter fullscreen mode Exit fullscreen mode

JavaScript has built-in debugging capabilities that are usually accessed through developer tools in browsers. For example, the console.log function can be used to print values to the console, and the debugger statement can be used to set a breakpoint in your code.

console.log('Hello, World!'); // Outputs: "Hello, World!"

function buggyFunction() {
  debugger; // Execution will stop here
  // Rest of the function
}
Enter fullscreen mode Exit fullscreen mode

These tools and concepts are essential to understand and handle errors in your JavaScript code.

Top comments (0)