The difference between traditional functions and arrow functions in javascript

Arrow functions are a new way to write function expressions in Javascript. They use ES6 (ECMAScript 6) and have a shorter and nicer syntax. But they are not the same as regular functions. They have some differences that we need to pay attention to.

Syntax

The difference in syntax between the two models is notorious, since in the arrow function it becomes possible to considerably reduce the number of lines present in the function declaration, especially if it is already a simple function. See examples:

Imagine a function that takes a user's name and prints it to the console. In the traditional way, we could declare it like this:

function sayMyNane(name){
  console.log(`My name is ${name}!`);
}

sayMyNane('Ernane'); // => My name is Ernane.

Already with the arrow functions present from ES6, we could do it as follows:

const sayMyName = (name) => {
  console.log(My name is ${name});
}

sayMyNane('Ernane'); // => My name is Ernane.

Remembering that in the case of arrow functions, the braces are only necessary if an expression is present, the same rule applies for parentheses, since they are only necessary if there is more than one argument to be passed. In this way, we could reduce it even further and write the above example as follows:

const sayMyName = name => console.log(My name is ${name}; 

sayMyNane('Ernane'); // => My name is Ernane.

Simple, isn't it? ✨ in this way, we can see how an arrow function can facilitate the declaration of a certain function because of its syntax and still return the same result as a common declaration.

Use of the 'this' keyword

Unlike the traditional declaration, arrow functions do not have their own this element, as the value of this inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of this in the closest traditional parent function.

Did that get a little weird? 🤔 let me try to uncomplicate with an example:

Returning to the example used in the previous topic, imagine that we have a person object that has its name defined as one of its attributes and has a function that prints the name of that particular person to the console. Depending on the type of function used, it will not be able to correctly access the parent object that has the requested name attribute and, therefore, its return will be undefined.

let person = {
  name: "Ernane Ferreira",
  sayMyName: () => console.log(My name is ${this.name}.)
};

person.sayMyName(); // => My name is .

In the case of the function being declared in the traditional model, this will work as expected and we will correctly obtain the sought attribute. 🤗

let person = {
  name: "Ernane Ferreira",
  sayMyName: function() {
    console.log(My name is ${this.name}.);
  }
};

person.sayMyName(); // => My name is Ernane Ferreira.

Access to arguments

The arguments object is a local variable available inside all functions and it is what makes the reference possible arguments of a function within the same using the arguments object. However, arrow functions have no link to the arguments object:

const showArguments = () => console.log(arguments);

showArguments(1, 2, 3) // => ReferenceError: arguments is not defined.

In the case of a regular function, we can easily access a list of the arguments passed as a parameter when calling the function:

function showArguments(){ 
  console.log(arguments); 
}

showArguments(1, 2, 3) // => Arguments(3) [1, 2, 3]

Using the new operator

The new operator allows instantiation of a user-defined object type or one of the user-defined types. of internal objects that have a constructor function. Traditional functions are constructible and can be called using the new operator. On the other hand, arrow functions are callable and not constructible, that is, these functions can never be used as constructor functions and can never be invoked with the new operator.

Therefore, for this type of execution in traditional functions, we get the following execution result:

function sayMyName(){
  console.log(My name is ${name}); 
}

new sayMyName('Ernane'); // => Ernane

As for the arrow functions:

const sayMyName = () => console.log(My name is ${name});

new sayMyName('Ernane'); // => Uncaught TypeError: sayMyName is not a constructor

Parameters with duplicate naming

The arrow functions do not allow the name of duplicate parameters, but the traditional functions allow depending on the application or non-application of strict mode (Strict Mode) in the code implementation. For example, the javascript below is fully valid:

function addTwoNumbers(x, x){
  console.log(x+x);
}

addTwoNumbers(1,1); // => 2

However, the same code with strict mode applied is no longer valid:

'use strict';

function addTwoNumbers(x, x){
  console.log(x+x);
} 

// => Uncaught SyntaxError: Duplicate parameter name not allowed in this context

When using arrow functions, this occurs regardless of whether strict mode is applied. In both cases, the execution is invalid:

const addTwoNumbers = (x, x) => console.log(x+x); 

// => SyntaxError: Uncaught SyntaxError: Duplicate parameter name not allowed in this context.

That way, it's always good to pay close attention to the use of arrow functions instead of traditional functions. Although their syntax is very pleasant, they have some points that we must be careful not to miss.

In any case, further study on the subject is advisable. As always, I will leave below some recommendation links for the deepening of the theme.

I hope you enjoyed this post and that it helped you find what you were looking for! 💙

Links

No comments:

Post a Comment