This is a continuation of my last post if you missed the first series, please read it here.
We would go into a quick introduction to the following.
- Promises
- Classes
- Functional Programming(Higher-Order Functions)
I will write a list of websites you can visit to learn more in details (References)
Promises
A Promise in JavaScript looks like a promise made in real life. As promises in real life are either kept or broken, JavaScript Promises get either resolved or rejected.
A Promise is an object representing the eventual completion or failure of an asynchronous operation.
What is an asynchronous operation?
Asynchronous operation is a process operates independently of other processes.
Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.
Imagine a function, createUserAccount()
, which asynchronously generates a creates a new user account on an insurance company website and has two callback functions, one called if the user account was created successfully, and the other called if an error occurs.
function successfulRegistration(username) { return `${username} has been successfully created`; } function failedRegistration(error_message) { return error_message; } createUserAccount(verifyUser, successCallback, failureCallback);
If createUserAccount()
were rewritten to return a promise, it would look like the following below
createUserAccount(verifyUser).then(successCallback, failureCallback);
The constructor syntax for a promise object is
var promiseObject = new Promise(executor);
var promiseObject = new Promise(function(resolve, reject) { if (/* everything turned out fine */) { Â Â Â Â resolve("Stuff worked!"); Â Â } Â Â else { Â Â Â Â reject(Error("It broke")); Â } });
The above promise constructor takes one argument, a callback with two parameters, resolve and reject. If an action was completed then call resolve, if not, otherwise call reject.
A Promise is in one of these states:
- pending: initial state, neither fulfilled nor rejected.
- fulfilled: meaning that the operation completed successfully.
- rejected: meaning that the operation failed.
To fully understand the concept of promises, let’s create a simple app that makes a request to an API using the user_id.
If the promise is successful, the data will load, if unsuccessful, an error will occur:
const getUser = user_id => new Promise((resolves, rejects) => { const api = `https://fakeurl.com/${user_id}` const request = new XMLHttpRequest(); request.open('GET', api); req.onload = () => { if (req.status == 200) { resolve(req.response); } else { reject(req.statusText); } }; request.onerror = () => reject(request.statusText); request.send(); });
Classes
A class is a type of function, but instead of using the keyword function to initiate it, we use the keyword class, and the properties are assigned inside the constructor() method.
Class declarations
class User { constructor(name,age,email) { this.age = age; this.name = name; this.email = email; } }
NOTE:
The constructor() method is a special method for creating and initializing an object created with a class. There can only be one special method with the name “constructor” in a class.
A SyntaxError will be thrown if the class contains more than one occurrence of a constructor() method.
PROTOTYPE METHODS IN CLASSES
class User { constructor(name, age, email) { this.age = age; this.name = name; this.email = email; } returnAge() { return `My name is ${this.name} and I'm ${this.age } years old`; } }
Now
- Create a new instance of the class using the new keyword.
- Then you can call the custom method on the class
const user = new User("Mark", 24, "mark@gmail.com"); console.log(user.returnAge()); //My name is Mark and I'm 24 years old
Static Methods
Static methods are defined on the class itself, and not on the prototype.
That means you cannot call a static method on the object (user), but on the class (User)
class User { constructor(name,age,email) { this.age = age; this.name = name; this.email = email; } returnAge() { return `My name is ${this.name} and I'm ${this.age } years old`; } static salutations() { return "Hello,nice to meet you!"; } } greeting = User.salutations(); console.log(greeting) // Hello,nice to meet you!
To use the user object inside the static method, we need to send it as a parameter:
class User { constructor(name,age,email) { this.age = age; this.name = name; this.email = email; } returnAge() { return `My name is ${this.name} and I'm ${this.age } years old`; } static salutations(user_field) { return `Hello ${user_field.name} ,nice to meet you!`; } } const user = new User("Mark", 24, "mark@gmail.com"); console.log(User.salutations(user)) // Hello Mark ,nice to meet you!
Inheritance
To create a class inheritance, use the `extend` keyword.
If there is a constructor present in the subclass, it needs to first call super() before using this.
class User { constructor(name,age,email) { this.age = age; this.name = name; this.email = email; } returnAge() { return `My name is ${this.name} and I'm ${this.age } years old`; } static salutations(user_field) { return `Hello ${user_field.name} ,nice to meet you!`; } } class VerifiedUser extends User { constructor(name, state) { super(name); this.state = state; } verifyUserLocation() { return `Hello ${this.name},you stay at ${this.state}!`; } } user = new VerifiedUser("Tom", "Georgia"); console.log(user.verifyUserLocation()) //Hello Tom,you stay at Georgia!
Functional Programming(Higher-Order Functions)
A function that accepts and/or returns another function is called a higher-order function.
Map(), Filter(), Reduce()
are all higher-order functions (array methods) in JavaScript. Each one iterates over an array and perform a modification or computation and returns a new array based on the result of the function.
Let me show you a funny illustration
Map
The map() is a method used for creating a new array from an existing one by calling a function for every array element (transforming arrays).
Transforming every element in an array into a new one and collecting the results is called mapping.
Syntax
var new_array = arr.map(function callback(currentValue, index, array) { // Return value for new_array })
Only the currentValue(value of the current element) is required, but other function parameters (index and array)are optional. The index represents the array index of the current element and array is the array object the current element belongs to.
Examples:
- Let’s change an array of strings to UpperCase letters
- Find the square root for an array of numbers.
const letters = ["georgia","london","usa","uae"]; const upper_case = letters.map(letter => letter.toUpperCase()); console.log(upper_case); // Array(4) [ "GEORGIA", "LONDON", "USA", "UAE" ] const nums = [450,56,9,16,64]; const num_root = nums.map(Math.sqrt); console.log(num_root); // Array(5) [ 21.213203435596427, 7.483314773547883, 3, 4, 8 ]
filter
The filter() method creates an array filled with all array elements that pass a test (provided as a function). The function should return true to keep the element, or false otherwise (like a boolean)
Syntax
var new_array = arr.filter(function callback(currentValue, index, array) { // Return value for new_array })
The syntax of the filter() is similar to the map() method,only the currentValue is required, but other function parameters (index and array)are optional.
Examples:
- Let’s return only arrays of numbers greater than 1000
- Let’s return only arrays of strings that start with Y
const letters = ["You are good!","Hello", "arriving","Yellow Sun"]; const startWithY = letters.filter(letter => letter.startsWith("Y")); console.log(startWithY); // [ "You are good!", "Yellow Sun" ] const numbers = [40000,678000,678,340,3456]; const num = numbers.filter(item => item > 1000); console.log(num); // [ 40000, 678000, 3456 ]
Reduce
The reduce method reduces the array to a single value.
Syntax
array.reduce(function(initialValue, currentValue, currentIndex, array))
The initialValue (the total previously returned value of the function)Â and currentValue (the value of the current element) are both required, but other function parameters (index and array)are optional.
Example:
- Let’s imagine a bank log transaction that shows all the credit transaction a customer carried out, let’s return the final customer balance after each transaction.
const transactions = [570, 5679, 567, 234,6700]; transactions.reduce(function (totalBalance, nextTransaction) { console.log(`Your current bank balance: ${totalBalance}`) // update totalBalance by adding the next credit transaction totalBalance += nextTransaction }) //Output Your current bank balance: 570 Your current bank balance: 6249 Your current bank balance: 6816 Your current bank balance: 7050
If you made it to the end of this series, a big congratulations 🎉🎉 and thank you for reading.
I love to hear your feedback and don’t forget to subscribe, so you stay updated when I publish a new post.
References
- W3schools
- Learning React -Alex Banks and Eve Porcello
- MDN web docs
- Freecodecamp
- Web.dev
- JavaScript.info
I blog quite often and I really thank you for your content. This great article has truly peaked my interest. I will book mark your website and keep checking for new details about once per week. I subscribed to your Feed as well.
Thank you, Ali