Make no mistake, it's not just the compactness and elegant syntax that differ the ways of declaring functions in Javascript.
Arrow functions is a relatively new feature implementing in ES6 (ECMAScript 6) which in our eyes is just a more concise and elegant syntax to declare function expressions in Javascript. Although traditional functions and arrow functions work in a similar way, we must beware of certain differences that may not be noticeable.
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! π
Top comments (6)
You missed out one important feature of an arrow function - implicit one line return i.e. if your code evaluates on one line and you don't use
{ }
a code block, then you can return from the function without using thereturn
statement.Additionally your statement implies that function declarations have their own
this
which is not true.Also arrow functions do have a
this
it's just bound to lexical scope i.e. whateverthis
points to in the scope of where you wrote the function.Π‘ongratulations π₯³! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up π
I find the normal way far easier to read because that's how most other languages also work. It's has more white space and is easier to read line by line.
Awesome article π
No they donβt. Functions and Lambdas (fat arrow function) are completely different things that generate similar results. Saying they are the same is akin to say + and * are the same because
Therefore + and * are the same
Exactly! If you continue reading, you will see that this paragraph is just a comparison to draw the reader's attention. The purpose of this publication is to literally emphasize this difference and the necessary care that we must have when using one or the other.