Programming with JavaScript

⌘K
  1. Home
  2. Docs
  3. Programming with JavaScri...
  4. Advance Javascript Module...
  5. ES6 Arrow Functions

ES6 Arrow Functions

ES6 Arrow Functions

Arrow functions were introduced in ECMAScript 2015 (ES6) as a concise way to define functions in JavaScript. The syntax is intuitive and compact when comparing to traditional function expressions. The basic syntax is as follows:

const funName = (parameters) => {
	//function body

	return value.
}

const: Arrow functions are often assigned to a variable using the ‘const’ keyword to create a function expression.

‘funName’: This is the name of the function. Arrow functions can be anonymous or have a name (in case of named function expressions). If the arrow function is anonymous, one can still call it using the variable to which it is assigned

‘parameters’: These are the input parameters of the function, similar to regular function parameters. If there’s only one parameter, the parentheses can be omitted. For zero or multiple parameters, parentheses are required.

‘=>’: The fat arrow ‘=>’ separates the parameter list from the function body. It indicates that it’s an arrow function

‘{}’: The curly braces represent the function body, where the actual code of the function resides. If the function has a single expression as its body, the curly braces can be omitted.

‘return’: If the function body consists of a single expression, the ‘return’ keyword can be omitted. The function will implicitly return the result of that expression.

ES6 Arrow Functions – Syntax

// arrow function with only one expression 
(a,b) => a+b; // implicit return of a+b
 
// arrow function with one statement can be wrapped inside parenthesis with return statement
(a,b) => {
return a+b; // explicit return of a+b
}
 
// arrow function with only one argument
a => a*a; // omit ( ) with one parameter
 
// arrow function with no arguments returning constant value
() => 2; // ( ) are mandatory without any parameters
 
// arrow function returning object; explicit return of the object
(a,b) => {
   return {
     a1:a;
    b1:b
}

// implicit return of the object
(a,b) => (
{
	a1: a,
  b1:b
}
)

Example1:

Arrow function for adding two numbers

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

console.log(sum(2, 3));

When trying to access the function sum before the expression results in reference error.

//console.log(sum(2, 3)); //ReferenceError: Cannot access 'sum' before initialization

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

Example 2:

Arrow functions to return an object explicitly

const post = {
  title: "JavaScript",
  comments: 10,
  shared: true,
  published: true,
  postId: 2124,
};

const postprocess = (post) => {
  return {
    title: post.title,
    comments: post.comments,
    popular: post.comments > 5 ? true : false,
  };
};

console.log(postprocess(post));

Output

The above example takes object as an argument and process the property of an object using ternary operator.

Example 3:

Arrow functions to return an object implicitly

const post = {
  title: "JavaScript",
  comments: 10,
  shared: true,
  published: true,
  postId: 2124,
};

const postprocess = (post) => ({
  title1: post.title,
  comments1: post.comments,
  popular: post.comments > 5 ? true : false,
});

console.log(postprocess(post));

Output

Immediately Invoked Function Expression

Immediately invoked Function Expression (IIFE)

The key to create an IIFE with arrow functions is to wrap the arrow function in parentheses and invoke it immediately.

() => {
  const msg = "Welcome all";
  console.log(msg);
}

The above piece of code has to be wrapped within ( ) and it is followed by (); to invoke it immediately.

(() => {
  const msg = "Welcome all";
  console.log(msg);
})();

IIFE with parameter

((name) => {
  console.log("Welcome \t" + name);
})("Raji");

Arrow Functions don’t own this

Arrow functions don’t have own “this”. “this” in arrow functions is always statically defined by the surrounding lexical scope.

const number = {
  value: 1002,
  fun1: function funct() {
    console.log(this);
    return this.value;
  },
};

console.log(number.fun1());
//arrowfunction
const number1 = {
  value: 1002,
  funa: () => {
    console.log("Inside arrow", this);
    return this.value;
  },
};

console.log(number1.funa());

Output

In the case of arrow functions, the value of ‘this’ is not determined by how the function is called, but by the surrounding lexical context in which the arrow function is defined. In this example, the arrow function ‘funa’ is defined inside the ‘number1’ object. However, since its an arrow function, it does not have its own ‘this’ binding and instead inherits ‘this’ from the surrounding scope, which is the global scope (or the object that encloses ‘number1 object).

Since, the call number1.funa(), the arrow function is executed in the context of the global object (E.X: ‘window’ in browsers), that is providing the output ‘{ }’ as the value of ‘this’. In the global context, there is no property ‘value’, so ‘this.value’ returns ‘undefined’.

To access the ‘value’ propery of the ‘number1’ object correctly, one should use a regular function instead of an arrow function for ‘funa’ which will bind its own ‘this’ context based on how it is called ( as a method of ‘number1’)

Using arrow functions within object methods is generally not recommended when need to access to the object’s properties through ‘this’, as they won’t provide the desired behavior of ‘this’ referring to the object itself. Regular functions are better suited for methods that rely on object properties and their context.

const num1 = {
  value1: 100,
  fun1: function () {
    console.log(this);
    return this.value1;
  },
};

const num2 = {
  value2: 200,
};

console.log(num1.fun1.call(num2));

Using arrow function

const num1 = {
  value1: 100,
  fun1: () => {
    console.log(this);
    return this.value1;
  },
};

const num2 = {
  value2: 200,
};

console.log(num1.fun1.call(num2));

In arrow functions, this is not dynamically scoped like in regular functions. Instead, arrow functions inherit the value of this from the surrounding context, which, in this case, is the global scope (e.g., window object in a browser).

When you call num1.fun1.call(num2), the arrow function fun1 is executed within the global scope, not within the num1 object. That’s why this points to the global scope (an empty object representing the global context), and this.value1 is undefined, as there is no value1 property in the global scope.

const str = {
  value: "Greetings",
  greet: function greet() {
    //   const self = this;
    setTimeout(function () {
      console.log(this);
      console.log(this.value);
    }, 1000);
  },
};

str.greet();

Function Constructor

A constructor function is designed to be used with the ‘new’ keyword to create instances (objects) of a particular type. When you call a constructor function using the ‘new’ keyword, it creates a new object and sets the ‘this’ context of the function to that object. Inside the constructor function, one can define properties and methods on the object using the ‘this’ keyword. The Syntax is shown as:

const myfun = new Functionname(arg1, arg2, …., argN, functionBody);

Here,

  • ‘arg1, arg2, …., argN’” the arguments (parameters) for the function. These are optional
  • ‘functionBody’: A string containing the code that defines the function;s behavior.
  • The ‘GroceryItem’ function is a constructor function. It takes ‘title’ and ‘kind’ parameters and assigns them as properties of the newly created object using ‘this.title’ and ‘this.kind’
function GroceryItem(title, kind) {
  this.title = title;
  this.kind = kind;
}

Then, instances (objects) can be created for ‘GroceryItem’ using the ‘new’ keyword:

For example

const mango = new GroceryItem("Mango", "fruit");

Constructor function and function constructor refer to the same concept in JavaScript, which is a function that is used to construct and initialize objects.

Arrow functions cannot be used as Function Constructor (constructor function).

function GroceryItem(title, kind) {
  this.title = title;
  this.kind = kind;
}

const mango = new GroceryItem("Mango", "fruit");
console.log(mango);

const potato = new GroceryItem("Potato", "vegetable");
console.log(potato);

Output

Arrow functions are anonymous, expressions, not owning this

Practice Exercises

Convert the following regular expression to arrow functions

function add(a, b) {
  return a + b;
}
Solution: 
const add = (a, b) => a + b;
function square(x) {
  return x * x;
}
Solution: 
const square = x => x * x;

Illustrate the lexical ‘this’ behavior of arrow functions within an object:

const person = {
  name: "John",
  sayHello: function() {
    console.log(`Hello, my name is ${this.name}.`);
  },
  sayHelloArrow: () => {
    console.log(`Hello, my name is ${this.name}.`);
  }
};

Convert function expression to arrow function

const greet = function(name) {
return ‘Hello, ${name}!’;
};
Solution: 
const greet = name => `Hello, ${name}!`;

In this example, the sayHello method is a regular function and ‘this’ inside the function refers to the ‘person’’ object. However, the ‘sayHelloArrow’ method is an arrow function, and ‘this’ inside it refers to the global object (ex: window). Arrow functions do not create their own ‘this’ context, so they inherit the value of ‘this’ from the surrounding lexical scope

Loading

Views: 6

How can we help?

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments