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"
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"
});
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();
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!"
}
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
}
These tools and concepts are essential to understand and handle errors in your JavaScript code.
Top comments (0)