Difference between traditional functions and arrow functions in JavaScript

Make no mistake, Javascript’s way of declaring functions is not just about compactness and elegant syntax.

Arrow functions are a relatively new feature implemented in ES6 ( ECMAScript 6 ), which, in our opinion, is simply a more concise and elegant syntax for declaring function expressions in JavaScript. Although traditional and arrow functions work in a similar way, we must beware of some differences that may not be noticeable.

Syntax

The difference in syntax between the two models is well-known, because in an arrow function it becomes possible to significantly 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 username 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.

With ES6 arrow functions, we could do it like this:

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

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

Keeping in mind that, in the case of arrow functions, curly braces are only needed if an expression is present, the same rule applies to braces, since they are only needed if more than one argument needs to be passed. So we could reduce it even more and write the above example like this:

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

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

Simple, right? So we can see how an arrow function can make it easier to declare a certain function because of its syntax, and still return the same result as a normal declaration.

Using the keyword “this”

Unlike a traditional declaration, arrow functions do not have their own element. this because the this value inside an arrow function remains the same throughout the function’s lifecycle and is always bound to the this value in the nearest traditional parent function.

Did it get a little weird? Let me try to simplify with an example:

Returning to the example used in the previous section, imagine we have an object person, whose name is defined as one of its attributes, and a function that prints that particular person’s name to the console. Depending on the type of function being used, it will not be able to correctly access the parent object that has the requested attribute name and hence 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 a function declaration in the traditional model, this will work as expected and we will correctly get the desired attribute.

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

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

Argument Access

An object arguments is a local variable available inside all functions, and is what makes the reference possible arguments to the function inside it, using the arguments object. However, arrow functions do not have a reference to argumentsan object:

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

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

In the case of a normal function, we can easily access the list of 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

Operator new allows you to create instances of a user-defined object type or one of the user-defined types. internal objects that have constructor function . Traditional functions are constructible and can be called with the operatornew. On the other side, arrow functions are callable and not constructible, that is, these functions can never be used as constructor functions and can never be called with the operator new.

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

Concerning arrow functions :

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

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

Duplicate Name Parameters

Turnouts functions do not allow duplicate parameter names, but traditional functions allow a dependency on the use or non-use of strict mode ( Strict mode ) in the code implementation. For example, the JavaScript below is completely 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.

Thus, it is always a good idea to pay close attention to the use arrow functions instead of traditional features. While their syntax is very nice, there are some things we need to be careful about so we don’t miss them.

In any case, further study of this issue is recommended. As always, I’ll leave a few reference links below to deepen the topic.

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

Links

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *