Modern JavaScript Coding Examples

Modern JavaScript Coding Examples

Arrow Functions, Basic Arrow Function Syntax, Implicit Return Arrow Functions, Arrow Functions with Object Destructuring, Arrow Functions with Array Methods, Arrow Functions with Multiple Parameters, Template Literals, Example : Basic String Interpolation , Example : Multiline Strings , Example : Complex Expressions , Example : Nested Template Literals , Example : Using Template Literals with Functions , Destructuring, Example : Object Destructuring , Example : Array Destructuring , Example : Function Parameter Destructuring , Example : Renaming Destructured Properties , Example : Default Values in Destructuring , Spread Syntax, Example : Concatenating Arrays , Example : Copying Arrays , Example : Merging Objects , Example : Passing Arguments to Functions , Example : Removing Elements from Arrays , Promises, Basic Promise Syntax, Promise Chaining, Handling Promise Errors, Using Promise.all(), Using Promise.race(), Async/Await, Example : Basic async/await usage , Example : Parallel async/await usage , Example : Chained async/await usage , Classes, Example : Class definition , Example : Class inheritance , Example : Static methods , Example : Getters and setters , Example : Method chaining , Array Methods, Example : forEach() , Example : map() , Example : filter() , Example : reduce() , Example : find() , Object Methods, Example : Object.keys() , Example : Object.values() , Example : Object.entries() , Example : Object.assign() , Example : Object.freeze() , Default Parameters, Example : Basic usage , Example : Default parameter expressions , Example : Default parameters with destructuring

Arrow Functions:

Arrow functions are a concise way to write JavaScript functions. They have a shorter syntax than traditional functions and automatically bind the context of this.

// Traditional Function

function add(a, b) {

  return a + b;

}

// Arrow Function

const add = (a, b) => a + b;

Arrow functions provide a more concise and readable way to write functions in JavaScript.

// Using Arrow Functions to Filter an Array

const numbers = [1, 2, 3, 4, 5];

const filteredNumbers = numbers.filter(num => num % 2 === 0);

console.log(filteredNumbers);

// Output: [2, 4]

Arrow functions provide a more concise and readable way to write functions in JavaScript. Here are some examples of how to use arrow functions with explanations and source code:

Basic Arrow Function Syntax:

// Basic Arrow Function Syntax

const multiply = (a, b) => {

  return a * b;

};

console.log(multiply(2, 3)); // Output: 6

In this example, an arrow function is defined to multiply two numbers. The arrow function has a parameter list (a, b) and a function body { return a * b; }. The arrow function is then called with multiply(2, 3) and the result is logged to the console.

Implicit Return Arrow Functions:

// Implicit Return Arrow Functions

const multiply = (a, b) => a * b;

console.log(multiply(2, 3)); // Output: 6

In this example, the same multiplication arrow function is defined, but without the curly braces and return keyword. Instead, the result is implicitly returned by the arrow function.

Arrow Functions with Object Destructuring:

// Arrow Functions with Object Destructuring

const person = { name: ‘John Doe’, age: 30 };

const getName = ({ name }) => name;

console.log(getName(person)); // Output: “John Doe”

In this example, an arrow function is defined to extract the name property from an object using object destructuring. The arrow function takes an object as a parameter and extracts the name property using { name }. The arrow function is then called with getName(person) and the result is logged to the console.

Arrow Functions with Array Methods:

// Arrow Functions with Array Methods

const numbers = [1, 2, 3, 4, 5];

const squaredNumbers = numbers.map(num => num * num);

console.log(squaredNumbers); // Output: [1, 4, 9, 16, 25]

In this example, an arrow function is used with the map method to square each number in an array. The arrow function takes a single parameter num and returns num * num as the result.

Arrow Functions with Multiple Parameters:

// Arrow Functions with Multiple Parameters

const add = (a, b) => a + b;

console.log(add(2, 3)); // Output: 5

In this example, an arrow function is defined to add two numbers. The arrow function has two parameters a and b, and returns the sum of the two parameters using a + b. The arrow function is then called with add(2, 3) and the result is logged to the console.

Overall, arrow functions provide a more concise and readable way to write functions in JavaScript. They are especially useful with array methods, object destructuring, and multiple parameters.

Template Literals:

Template literals are a way to create string literals with embedded expressions. They make it easier to concatenate strings and variables without using the + operator.

const name = ‘John Doe’;

const age = 30;

// Using Template Literals

const message = `My name is ${name} and I am ${age} years old.`;

console.log(message);

// Output: “My name is John Doe and I am 30 years old.”

Template literals provide a way to concatenate strings and variables in a more readable and convenient way.

// Using Template Literals to Format Strings

const name = ‘John Doe’;

const age = 30;

const greeting = `Hello, my name is ${name} and I am ${age} years old.`;

console.log(greeting);

// Output: “Hello, my name is John Doe and I am 30 years old.”

In this example, a template literal is used to concatenate a string and variables. The variables are wrapped in ${} for easier formatting.

Example 1: Basic String Interpolation

const name = ‘John’;

const age = 25;

const message = `My name is ${name} and I am ${age} years old.`;

console.log(message); // Output: “My name is John and I am 25 years old.”

In this example, we define two variables name and age and use them to create a message using a Template Literal. The ${} syntax is used to interpolate the variables directly into the string.

Example 2: Multiline Strings

const message = `

  Hello,

  How are you doing today?

  Regards,

  John

`;

console.log(message);

// Output:

// ” 

//   Hello,

//   

//   How are you doing today?

//   

//   Regards,

//   John

// “

In this example, we define a message variable that contains a multiline string using a Template Literal. We can use the backticks (`) to create multiline strings without having to concatenate multiple strings together.

Example 3: Complex Expressions

const number = 5;

const message = `The square of ${number} is ${number * number}`;

console.log(message); // Output: “The square of 5 is 25”

In this example, we use a Template Literal to create a message that includes a complex expression. We can use any JavaScript expression inside the ${} syntax, including mathematical operations or function calls.

Example 4: Nested Template Literals

const firstName = ‘John’;

const lastName = ‘Doe’;

const fullName = `${firstName} ${lastName}`;

const message = `My name is ${fullName.toUpperCase()}`;

console.log(message); // Output: “My name is JOHN DOE”

In this example, we define a fullName variable that is created by concatenating the firstName and lastName variables using a Template Literal. We then use a nested Template Literal to create a message that includes the uppercase version of the full name.

Example 5: Using Template Literals with Functions

function formatName(firstName, lastName) {

  return `${lastName}, ${firstName}`;

}

const firstName = ‘John’;

const lastName = ‘Doe’;

const fullName = formatName(firstName, lastName);

console.log(fullName); // Output: “Doe, John”

In this example, we define a formatName() function that takes firstName and lastName arguments and returns a formatted string using a Template Literal. We then use the function to create a fullName variable by passing in the firstName and lastName variables.

Destructuring:

Destructuring is a way to extract values from arrays and objects and assign them to variables. It can make code more readable and concise.

// Destructuring an Array

const numbers = [1, 2, 3];

const [first, second, third] = numbers;

console.log(first, second, third);

// Output: 1 2 3

// Destructuring an Object

const person = { name: ‘John Doe’, age: 30 };

const { name, age } = person;

console.log(name, age);

// Output: “John Doe” 30

Destructuring is a way to extract values from objects and arrays and assign them to variables. It provides a more concise and readable way to access nested data.

// Destructuring Objects and Arrays

const person = {

  name: ‘John Doe’,

  age: 30,

  address: {

    city: ‘New York’,

    state: ‘NY’

  }

};

const { name, age, address: { city, state } } = person;

console.log(name, age, city, state);

// Output: “John Doe 30 New York NY”

const numbers = [1, 2, 3];

const [a, b, c] = numbers;

console.log(a, b, c);

// Output: “1 2 3”

In this example, object and array destructuring is used to extract values from nested data structures. The extracted values are assigned to variables for easier use in the code.

Example 1: Object Destructuring

const person = {

  firstName: ‘John’,

  lastName: ‘Doe’,

  age: 25,

  address: {

    city: ‘New York’,

    country: ‘USA’

  }

};

// Destructure firstName and lastName properties

const { firstName, lastName } = person;

console.log(firstName); // Output: “John”

console.log(lastName); // Output: “Doe”

// Destructure city and country properties from address

const { address: { city, country } } = person;

console.log(city); // Output: “New York”

console.log(country); // Output: “USA”

In this example, we define a person object with several properties, including an address object. We then use destructuring to extract the firstName and lastName properties directly into separate variables. We also use destructuring to extract the city and country properties from the nested address object.

Example 2: Array Destructuring

const numbers = [1, 2, 3, 4, 5];

// Destructure first two numbers into separate variables

const [first, second] = numbers;

console.log(first); // Output: 1

console.log(second); // Output: 2

// Destructure first and last numbers into separate variables

const [firstNumber, , , , lastNumber] = numbers;

console.log(firstNumber); // Output: 1

console.log(lastNumber); // Output: 5

In this example, we define an array of numbers. We then use destructuring to extract the first two numbers into separate variables, and to extract the first and last numbers into separate variables.

Example 3: Function Parameter Destructuring

function getUserInfo({ firstName, lastName, age }) {

  return `${firstName} ${lastName}, ${age} years old`;

}

const user = {

  firstName: ‘John’,

  lastName: ‘Doe’,

  age: 25

};

const userInfo = getUserInfo(user);

console.log(userInfo); // Output: “John Doe, 25 years old”

In this example, we define a getUserInfo() function that takes a single object argument and destructures its firstName, lastName, and age properties. We then define a user object and call the getUserInfo() function with it as the argument. The function uses the destructured properties to return a formatted string with the user’s information.

Example 4: Renaming Destructured Properties

const person = {

  firstName: ‘John’,

  lastName: ‘Doe’,

  age: 25,

  address: {

    city: ‘New York’,

    country: ‘USA’

  }

};

// Destructure firstName as fName, lastName as lName

const { firstName: fName, lastName: lName } = person;

console.log(fName); // Output: “John”

console.log(lName); // Output: “Doe”

In this example, we define a person object with several properties. We then use destructuring to extract the firstName and lastName properties and rename them as fName and lName, respectively. We can use this syntax to give destructured properties more meaningful names, or to avoid conflicts with existing variable names.

Example 5: Default Values in Destructuring

const person = {

  firstName: ‘John’,

  lastName: ‘Doe’,

  age: 25

};

// Destructure firstName and age with default values

const { firstName, age = 25 } = person;

console.log(firstName); // Output: “John”

console.log(age); // Output: 25

In this example, we define a person object with only firstName and lastName properties. We then use destructuring to extract the firstName property and also set a default value of 25 for the age property, since it is not present in the person object. The default value is used when the property is not present in the object or is set to undefined.

Spread Syntax:

Spread syntax allows an iterable such as an array or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.

// Using Spread Syntax to Merge Arrays

const arr1 = [1, 2, 3];

const arr2 = [4, 5, 6];

const mergedArr = […arr1, …arr2];

console.log(mergedArr);

// Output: [1, 2, 3, 4, 5, 6]

// Using Spread Syntax to Clone an Array

const originalArr = [1, 2, 3];

const clonedArr = […originalArr];

console.log(clonedArr);

// Output: [1, 2, 3]

The spread syntax allows an iterable (like an array or string) to be expanded into individual elements. It provides a more concise and readable way to manipulate arrays.

// Using the Spread Syntax to Manipulate Arrays

const numbers1 = [1, 2, 3];

const numbers2 = [4, 5, 6];

const combinedNumbers = […numbers1, …numbers2];

console.log(combinedNumbers);

// Output: [1, 2, 3, 4, 5, 6]

const slicedNumbers = […numbers1.slice(0, 2), …numbers2.slice(0, 2)];

console.log(slicedNumbers);

// Output: [1, 2, 4, 5]

In this example, the spread syntax is used to combine and manipulate arrays. The … operator is used to expand the arrays into individual elements.

Example 1: Concatenating Arrays

const numbers1 = [1, 2, 3];

const numbers2 = [4, 5, 6];

const concatenatedNumbers = […numbers1, …numbers2];

console.log(concatenatedNumbers); // Output: [1, 2, 3, 4, 5, 6]

In this example, we define two arrays numbers1 and numbers2. We then use the spread syntax (…) to concatenate the two arrays into a new array concatenatedNumbers.

Example 2: Copying Arrays

const originalArray = [1, 2, 3];

const copyArray = […originalArray];

console.log(copyArray); // Output: [1, 2, 3]

In this example, we define an array originalArray. We then use the spread syntax to create a new array copyArray with the same elements as originalArray. This technique can be used to create a shallow copy of an array.

Example 3: Merging Objects

const obj1 = { name: ‘John’ };

const obj2 = { age: 25 };

const obj3 = { city: ‘New York’ };

const mergedObject = { …obj1, …obj2, …obj3 };

console.log(mergedObject); // Output: { name: ‘John’, age: 25, city: ‘New York’ }

In this example, we define three objects obj1, obj2, and obj3. We then use the spread syntax to merge the three objects into a new object mergedObject.

Example 4: Passing Arguments to Functions

function addNumbers(a, b, c) {

  return a + b + c;

}

const numbers = [1, 2, 3];

const sum = addNumbers(…numbers);

console.log(sum); // Output: 6

In this example, we define a addNumbers() function that takes three arguments and returns their sum. We then define an array numbers with the values [1, 2, 3]. We use the spread syntax to pass the values of numbers as individual arguments to the addNumbers() function.

Example 5: Removing Elements from Arrays

const numbers = [1, 2, 3, 4, 5];

const [first, second, …rest] = numbers;

console.log(first); // Output: 1

console.log(second); // Output: 2

console.log(rest); // Output: [3, 4, 5]

In this example, we define an array numbers. We use the spread syntax to extract the first two elements of the array into separate variables first and second, and then use the rest syntax (…) to assign the remaining elements of the array to a new array rest.

Promises:

Promises are a way to handle asynchronous operations in JavaScript. They allow you to perform an action when an operation is completed, either successfully or unsuccessfully.

// Using Promises to Fetch Data from an API

const apiUrl = ‘https://jsonplaceholder.typicode.com/users’;

fetch(apiUrl)

  .then(response => response.json())

  .then(data => console.log(data))

  .catch(error => console.log(error));

In this example, the fetch function returns a promise that resolves with a Response object when the API call is completed. The then method is used to parse the response as JSON and log it to the console. The catch method is used to handle any errors that occur during the API call.

Promises are a way to handle asynchronous operations in JavaScript. They provide a more organized and reusable way to write asynchronous code.

// Using Promises to Fetch Data from an API

const apiUrl = ‘https://jsonplaceholder.typicode.com/users’;

fetch(apiUrl)

  .then(response => response.json())

  .then(data => console.log(data))

  .catch(error => console.log(error));

In this example, a promise is used to make an API call with fetch. The then method is used to parse the response as JSON and log the data. Any errors that occur during the API call are caught with the catch method.

Promises in JavaScript provide a way to handle asynchronous operations and their results. They are particularly useful when dealing with tasks that require waiting for an external service to return a result, such as an HTTP request to a server. Here are some examples of how to use promises in JavaScript with explanations and source code:

Basic Promise Syntax:

// Basic Promise Syntax

const promise = new Promise((resolve, reject) => {

  setTimeout(() => {

    resolve(‘Promise resolved’);

  }, 2000);

});

promise.then(result => {

  console.log(result); // Output: “Promise resolved”

});

In this example, a basic promise is created using the Promise constructor. The promise takes a function with two parameters, resolve and reject, which are used to indicate the success or failure of the promise. The promise resolves after a 2-second delay, returning the string “Promise resolved”. The then method is used to handle the successful result of the promise, and the result is logged to the console.

Promise Chaining:

// Promise Chaining

const promise1 = new Promise((resolve, reject) => {

  resolve(‘Promise 1 resolved’);

});

const promise2 = promise1.then(result => {

  return new Promise((resolve, reject) => {

    resolve(result + ‘, Promise 2 resolved’);

  });

});

promise2.then(result => {

  console.log(result); // Output: “Promise 1 resolved, Promise 2 resolved”

});

In this example, two promises are created using the Promise constructor. The first promise resolves with the string “Promise 1 resolved”. The then method is used to chain the first promise to a second promise, which returns a new promise that resolves with the combined result of both promises. The result is logged to the console using another then method.

Handling Promise Errors:

// Handling Promise Errors

const promise = new Promise((resolve, reject) => {

  setTimeout(() => {

    reject(new Error(‘Promise rejected’));

  }, 2000);

});

promise.catch(error => {

  console.error(error); // Output: “Error: Promise rejected”

});

In this example, a promise is created using the Promise constructor, which rejects after a 2-second delay with a new Error object. The catch method is used to handle the error that is thrown, and the error message is logged to the console.

Using Promise.all():

// Using Promise.all()

const promise1 = new Promise((resolve, reject) => {

  setTimeout(() => {

    resolve(‘Promise 1 resolved’);

  }, 2000);

});

const promise2 = new Promise((resolve, reject) => {

  setTimeout(() => {

    resolve(‘Promise 2 resolved’);

  }, 1000);

});

Promise.all([promise1, promise2]).then(results => {

  console.log(results); // Output: [“Promise 1 resolved”, “Promise 2 resolved”]

});

In this example, two promises are created using the Promise constructor, with different delays. The Promise.all method is used to handle multiple promises at once and returns a new promise that resolves with an array of all the successful results of the promises. The results are then logged to the console using a then method.

Using Promise.race():

const promise1 = new Promise((resolve, reject) => {

  setTimeout(() => {

    resolve(‘Promise 1 resolved’);

  }, 2000);

});

const promise2 = new Promise((resolve, reject) => {

  setTimeout(() => {

    resolve(‘Promise 2 resolved’);

  }, 1000);

});

Promise.race([promise1, promise2]).then(result => {

  console.log(result); // Output: “Promise 2 resolved”

});

In this example, two promises are created using the Promise constructor, with different delays. The Promise.race method is used to handle multiple promises at once and returns a new promise that resolves or rejects as soon as one of the promises in the array is resolved or rejected. In this case, the first promise resolves after 2 seconds, while the second promise resolves after 1 second. Since Promise.race returns the result of the first promise to resolve, the result of the second promise is ignored, and the result of the first promise is logged to the console using a then method.

Async/Await:

Async/await is another way to handle asynchronous operations in JavaScript. It provides a more readable and synchronous way to write asynchronous code.

// Using Async/Await to Fetch Data from an API

async function fetchData() {

  const apiUrl = ‘https://jsonplaceholder.typicode.com/users’;

  try {

    const response = await fetch(apiUrl);

    const data = await response.json();

    console.log(data);

  } catch (error) {

    console.log(error);

  }

}

fetchData();

In this example, the async function is used to make an API call with fetch. The await keyword is used to wait for the response and parse it as JSON. Any errors that occur during the API call are caught with a try/catch block.

Example 1: Basic async/await usage

async function getPosts() {

  try {

    const response = await fetch(‘https://jsonplaceholder.typicode.com/posts’);

    const data = await response.json();

    console.log(data);

  } catch (error) {

    console.log(error);

  }

}

getPosts();

In this example, we declare an async function called getPosts. Inside the function, we use the await keyword to make a request to the JSONPlaceholder API using the fetch function. We then parse the response using the json() method, and log the resulting data to the console.

Example 2: Parallel async/await usage

async function getPostsWithUsers() {

  try {

    const [postsResponse, usersResponse] = await Promise.all([

fetch(‘https://jsonplaceholder.typicode.com/posts’),

fetch(‘https://jsonplaceholder.typicode.com/users’)

    ]);

    const posts = await postsResponse.json();

    const users = await usersResponse.json();

    console.log({ posts, users });

  } catch (error) {

    console.log(error);

  }

}

getPostsWithUsers();

In this example, we declare an async function called getPostsWithUsers. Inside the function, we use the await keyword to make two parallel requests to the JSONPlaceholder API using the fetch function. We then parse the responses using the json() method, and log both sets of data to the console.

Example 3: Chained async/await usage

async function getUsersAndTheirPosts() {

  try {

    const usersResponse = await fetch(‘https://jsonplaceholder.typicode.com/users’);

    const users = await usersResponse.json();

    const usersWithPosts = await Promise.all(

      users.map(async user => {

        const postsResponse = await fetch(`https://jsonplaceholder.typicode.com/users/${user.id}/posts`);

        const posts = await postsResponse.json();

        return { …user, posts };

      })

    );

    console.log(usersWithPosts);

  } catch (error) {

    console.log(error);

  }

}

getUsersAndTheirPosts();

In this example, we declare an async function called getUsersAndTheirPosts. Inside the function, we use the await keyword to make a request to the JSONPlaceholder API to get all users, and parse the response using the json() method. We then use Promise.all to create an array of promises that fetch each user’s posts and returns a new object that includes the user’s data and their posts. Finally, we log the resulting data to the console.

Classes:

Classes are a way to create objects with shared properties and methods. They provide a more organized and reusable way to create objects.

// Creating a Class for a Person Object

class Person {

  constructor(name, age) {

    this.name = name;

    this.age = age;

  }

  sayHello() {

    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);

  }

}

// Creating an Instance of the Person Class

const person = new Person(‘John Doe’, 30);

person.sayHello();

// Output: “Hello, my name is John Doe and I am 30 years old.”

In this example, the class keyword is used to create a Person class with a constructor and sayHello method. An instance of the Person class is created with the new keyword and its sayHello method is called.

Example 1: Class definition

class Person {

  constructor(name, age) {

    this.name = name;

    this.age = age;

  }

  greet() {

    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);

  }

}

const john = new Person(‘John’, 25);

john.greet(); // Output: “Hello, my name is John and I am 25 years old.”

In this example, we define a Person class with a constructor that takes two parameters name and age. The class also has a greet() method that logs a greeting to the console. We create a new instance of the Person class using the new keyword and call the greet() method on the instance.

Example 2: Class inheritance

class Animal {

  constructor(name) {

    this.name = name;

  }

  speak() {

    console.log(`${this.name} makes a noise.`);

  }

}

class Dog extends Animal {

  constructor(name) {

    super(name);

  }

  speak() {

    console.log(`${this.name} barks.`);

  }

}

const dog = new Dog(‘Rufus’);

dog.speak(); // Output: “Rufus barks.”

In this example, we define an Animal class with a constructor that takes a name parameter and a speak() method that logs a noise to the console. We then define a Dog class that extends the Animal class and overrides the speak() method to make the dog bark instead of making a generic noise. We create a new instance of the Dog class and call the speak() method on the instance.

Example 3: Static methods

class Calculator {

  static add(a, b) {

    return a + b;

  }

  static subtract(a, b) {

    return a – b;

  }

}

const result1 = Calculator.add(2, 3);

console.log(result1); // Output: 5

const result2 = Calculator.subtract(5, 2);

console.log(result2); // Output: 3

In this example, we define a Calculator class with two static methods add() and subtract(). Static methods can be called on the class itself, rather than on an instance of the class. We call the static methods on the Calculator class to perform addition and subtraction operations.

Example 4: Getters and setters

class Rectangle {

  constructor(width, height) {

    this._width = width;

    this._height = height;

  }

  get width() {

    return this._width;

  }

  set width(value) {

    if (value > 0) {

      this._width = value;

    }

  }

  get height() {

    return this._height;

  }

  set height(value) {

    if (value > 0) {

      this._height = value;

    }

  }

  get area() {

    return this._width * this._height;

  }

}

const rectangle = new Rectangle(5, 10);

console.log(rectangle.area); // Output: 50

rectangle.width = 7;

console.log(rectangle.area); // Output: 70

In this example, we define a Rectangle class with two private properties _width and _height. We also define getter and setter methods for these properties, which allow us to get and set their values while enforcing a validation condition. We also define a getter method area() which calculates and returns the area of the rectangle. We create a new instance of the Rectangle class and call the area() method to get the initial area of the rectangle. We then use the setter methods to change the width of the rectangle and calculate the new area.

Example 5: Method chaining

class Car {

  constructor(make, model) {

    this.make = make;

    this.model = model;

    this.speed = 0;

  }

  accelerate(amount) {

    this.speed += amount;

    return this;

  }

  brake(amount) {

    this.speed -= amount;

    return this;

  }

  status() {

    console.log(`${this.make} ${this.model} is traveling at ${this.speed} mph.`);

    return this;

  }

}

const myCar = new Car(‘Toyota’, ‘Corolla’);

myCar.accelerate(30).status().brake(10).status(); // Output: “Toyota Corolla is traveling at 30 mph.”, “Toyota Corolla is traveling at 20 mph.”

In this example, we define a Car class with three methods: accelerate(), brake(), and status(). The accelerate() method increases the speed of the car, the brake() method decreases the speed of the car, and the status() method logs the current status of the car to the console. Each method returns the instance of the class itself to enable method chaining. We create a new instance of the Car class and call the accelerate(), status(), brake(), and status() methods in sequence to accelerate the car, log its status, brake the car, and log its status again.

Array Methods:

Modern JavaScript provides several new array methods that make it easier to manipulate and transform arrays.

// Using Array Methods to Filter and Map an Array

const numbers = [1, 2, 3, 4, 5];

const filteredNumbers = numbers.filter(num => num % 2 === 0);

console.log(filteredNumbers);

// Output: [2, 4]

const doubledNumbers = numbers.map(num => num * 2);

console.log(doubledNumbers);

// Output: [2, 4, 6, 8, 10]

In this example, the filter method is used to create a new array with only the even numbers from the numbers array. The map method is used to create a new array with each number from the numbers array doubled.

Example 1: forEach()

const fruits = [‘apple’, ‘banana’, ‘orange’, ‘grape’];

fruits.forEach(fruit => {

  console.log(fruit);

});

In this example, we define an array of fruits and use the forEach() method to loop through each fruit in the array and log it to the console. The forEach() method takes a callback function that is called for each element in the array.

Example 2: map()

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map(number => {

  return number * 2;

});

console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]

In this example, we define an array of numbers and use the map() method to create a new array that contains each number doubled. The map() method creates a new array with the same number of elements as the original array, but with each element transformed based on the callback function.

Example 3: filter()

const numbers = [1, 2, 3, 4, 5];

const evenNumbers = numbers.filter(number => {

  return number % 2 === 0;

});

console.log(evenNumbers); // Output: [2, 4]

In this example, we define an array of numbers and use the filter() method to create a new array that contains only the even numbers. The filter() method creates a new array with only the elements that pass the test specified by the callback function.

Example 4: reduce()

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, currentValue) => {

  return accumulator + currentValue;

}, 0);

console.log(sum); // Output: 15

In this example, we define an array of numbers and use the reduce() method to calculate the sum of all the numbers in the array. The reduce() method takes a callback function that specifies how to combine the elements of the array into a single value. In this case, we use the accumulator variable to keep track of the running total, and add each element in the array to it. The second argument to reduce() is the initial value of the accumulator variable.

Example 5: find()

const fruits = [‘apple’, ‘banana’, ‘orange’, ‘grape’];

const foundFruit = fruits.find(fruit => {

  return fruit === ‘orange’;

});

console.log(foundFruit); // Output: “orange”

In this example, we define an array of fruits and use the find() method to find the first fruit that matches the specified condition. The find() method returns the first element in the array that passes the test specified by the callback function. In this case, we use find() to find the first fruit that is equal to the string ‘orange’.

Object Methods:

Modern JavaScript also provides several new object methods that make it easier to manipulate and transform objects.

// Using Object Methods to Merge and Clone Objects

const obj1 = { name: ‘John Doe’, age: 30 };

const obj2 = { occupation: ‘Programmer’ };

const mergedObj = Object.assign({}, obj1, obj2);

console.log(mergedObj);

// Output: { name: ‘John Doe’, age: 30, occupation: ‘Programmer’ }

const clonedObj = { …obj1 };

console.log(clonedObj);

// Output: { name: ‘John Doe’, age: 30 }

In this example, the Object.assign method is used to merge the obj1 and obj2 objects into a new object. The spread syntax is used to clone the obj1 object.

Example 1: Object.keys()

const person = {

  name: ‘John’,

  age: 25,

  city: ‘New York’

};

const keys = Object.keys(person);

console.log(keys); // Output: [“name”, “age”, “city”]

In this example, we define an object person with three properties name, age, and city. We use the Object.keys() method to extract an array of the keys in the person object.

Example 2: Object.values()

const person = {

  name: ‘John’,

  age: 25,

  city: ‘New York’

};

const values = Object.values(person);

console.log(values); // Output: [“John”, 25, “New York”]

In this example, we define an object person with three properties name, age, and city. We use the Object.values() method to extract an array of the values in the person object.

Example 3: Object.entries()

const person = {

  name: ‘John’,

  age: 25,

  city: ‘New York’

};

const entries = Object.entries(person);

console.log(entries); // Output: [[“name”, “John”], [“age”, 25], [“city”, “New York”]]

In this example, we define an object person with three properties name, age, and city. We use the Object.entries() method to extract an array of the entries in the person object, where each entry is represented as a [key, value] pair.

Example 4: Object.assign()

const person = {

  name: ‘John’,

  age: 25

};

const address = {

  city: ‘New York’,

  zip: 10001

};

const merged = Object.assign(person, address);

console.log(merged); // Output: { name: ‘John’, age: 25, city: ‘New York’, zip: 10001 }

In this example, we define two objects person and address. We use the Object.assign() method to merge the two objects into a new object merged. The properties in address override the properties with the same name in person.

Example 5: Object.freeze()

const person = {

  name: ‘John’,

  age: 25

};

Object.freeze(person);

person.age = 30;

console.log(person); // Output: { name: ‘John’, age: 25 }

In this example, we define an object person. We use the Object.freeze() method to freeze the object, which prevents any modifications to its properties. We then try to modify the age property, which has no effect since the object is frozen.

Default Parameters:

Default parameters provide a way to specify default values for function parameters. They make it easier to write functions that can handle

JavaScript Default Parameters is a feature that allows you to specify default values for function parameters in case they are not passed in or are undefined. Here are a few examples of how to use default parameters in JavaScript:

Example 1: Basic usage

function greet(name = ‘World’) {

  console.log(`Hello, ${name}!`);

}

greet(); // Output: “Hello, World!”

greet(‘John’); // Output: “Hello, John!”

In this example, we define a greet() function that takes a name parameter. We set the default value of name to ‘World’. If name is not passed in or is undefined, the function will use the default value of ‘World’. We call the function twice, once without any arguments and once with the argument ‘John’.

Example 2: Default parameter expressions

function calculateTotal(price, taxRate = 0.1, discount = 0) {

  const tax = price * taxRate;

  const discountedPrice = price – (price * discount);

  const total = price + tax – discountedPrice;

  return total;

}

console.log(calculateTotal(100)); // Output: 10

console.log(calculateTotal(100, 0.15)); // Output: 15

console.log(calculateTotal(100, 0.15, 0.2)); // Output: 10

In this example, we define a calculateTotal() function that takes three parameters: price, taxRate, and discount. We set the default values of taxRate and discount to 0.1 and 0, respectively. We use these default values to calculate the total price if the user doesn’t pass in any values for taxRate or discount. We call the function three times, passing in different combinations of arguments to test the default values.

Example 3: Default parameters with destructuring

function printPersonInfo({ name = ‘John Doe’, age = 30, gender = ‘unknown’ } = {}) {

  console.log(`Name: ${name}, Age: ${age}, Gender: ${gender}`);

}

printPersonInfo(); // Output: “Name: John Doe, Age: 30, Gender: unknown”

printPersonInfo({ name: ‘Alice’, age: 25 }); // Output: “Name: Alice, Age: 25, Gender: unknown”

In this example, we define a printPersonInfo() function that takes an object with three properties: name, age, and gender. We use destructuring to extract these properties from the object and set their default values if they are not passed in or are undefined. We also set the default value of the entire object to an empty object {} so that the function can be called without any arguments. We call the function twice, once without any arguments and once with an object containing name and age properties.