Mariusz Rajczakowski
Software Engineer
7 min read | 4 months ago

Make your javascript code shorter with an arrow function

What is arrow function?

An arrow function, also known as fat arrow function is more concise syntax for writing a function expression, but it does not bind own this, arguments, super or new.target

Those functions cannot be used as function constructors, and non-method functions (lack of this bindings)

The biggest advantage of using arrow function is to accomplish the same result with fewer lines of code and much less typing.


                //basic usage with single argument
                const test = (param1) => { /* do something here */ }

                //when there is just one param you can skip parentheses
                const test2 = param2 => { /* do something here */ }

                //when do function body just return expression you might
                //go even further and skip curly braces
                const test3 = item => item.id;

                //which is equivalent to:
                function test3(item){
                  return item.id;
                }
                

However in some cases you must use parenthesis


                //arrow function without arguments
                const test4 = () = {  /* do something here */ };

                //arrow function with more than one arguments
                const test4 = (param1, param2) => { /* do something here */ } ;

                //rest operator
                const test5 = (...options) => { /* do something here */ } ;

                //default params
                const test5 = (param1 = [], param2 = true) => { /* do something here */ } ;
                

If you want to implicitly return an object and still want to omit curly braces you have to wrap your object with parenthesis


                const getTestItem = () => ({ name: 'test' }); // will return { name: 'test' }
                

If you ever come across something like this:


                const logger = store => next => action => {
                  console.log(action);
                  next(action);
                }
                

Don't be overwhelmed, as this pattern is called currying and it simply translates to:


                function logger(store){
                  return function(next){
                    return function(action){
                      console.log(action);
                      next(action);
                    }
                  }
                }
                

Typical use cases

Arrays operations

Whenever you encounter that your code is getting too verbose and function you are creating is not a method nor constructor, you may find this handy:


                const users = [
                  {id: 1, name: 'John', age: 26},
                  {id: 2, name: 'Thomas', age: 15},
                  {id: 3, name: 'Kate', age: 23 }
                ];
                const grownUps = users.filter(user => user.age > 18);
                //instead of more verbose:
                const grownUps2 = users.filter(function(user){
                  return user.age > 18;
                });
                

Shorter asynchronous syntax


                somePromise().then(function(response){ rerturn response.json(); })
                                        .then(function(response){ /* process response */ })
                                        .catch(function(error){ /* process errror */ });
                //can become
                somePromise().then(response => response.json())
                                        .then(response => { /* process response */ })
                                        .catch(error => { /* process error */ });
                

Using with this

Not binding this could be an advantage in certain situations, as functions declared with function keyword always declare new this.


                //part of an object
                //...
                saveItem: function() {
                  //we have to store this in a vm variable
                  // to have a reference to a parent object
                  let vm = this;
                  this.	$http.post('item', this.item).then(function (response) {
                     //'this' here points to function(response){} instead of parent object
                     //that's why we use vm instead
                      vm.item = response.item;
                  },function(error) {
                     console.log(error);
                  });
                }
                //with arrow function we don't need to store this in vm var
                //(as arrow function doesn't have own this)
                //...
                saveItem: function() {
                  this.	$http.post('item', this.item).then(response => {
                     //'this' here points to parent object
                     //that's why we don't need to use vm here
                      this.item = response.item;
                  }, error => {
                     console.log(error);
                  });
                }
                

Constructors

You cannot use arrow functions for object constructors. You should use either new ES2015 class syntax or ES5 function keyword for that.


                const Person = (name) => {
                  this.name = name;
                }
                const tom = new Person(); //throws TypeError: Person is not constructor

                //ES2015
                class Person{
                  constructor(name){
                    this.name = name;
                  }
                }
                const ann = new Person('Ann'); //creates an object { name: 'Ann' };

                //ES5
                const Person = function(name){
                  this.name = name;
                }
                const greg = new Person('Greg'); //creates an object { name: 'Greg' };
                

Not binding arguments

Arrow functions does not have own arguments


                const myFunction = () => { console.log(arguments) };
                myFunction(1, 'test'); //ReferenceError: arguments is not defined
                const myOtherFunction = function{ console.log(arguments); }
                myOtherFuncton(1, 'test'); // [1, 'test']
                //the workaround for this is to use rest operator
                const myFunc = (...args) => { console.log(args); }
                myFunc(1, 'test'); // [1, 'test']
                

Not the best fit for method functions

Arrow functions that not have own this, so using this inside of arrow function will point to the parent object


                const tom = {
                  name: 'Tom',
                  sayName: () => {
                      //this here points to global object - window
                      console.log(this.name); // will look for this.name on window.name and log undefined
                  }
                };
                tom.sayName();
                //instead of arrow function you should use:
                const tom = {
                  name: 'Tom',
                  sayName(){
                      //this here points to tom
                      console.log(this.name); // will log 'Tom'
                  }
                };
                tom.sayName();
                

No prototype

Arrow functions does not have prototype property


                const Animal = () =>  {};
                console.log(Animal.prototype); //undefined
                

No generators

Arrow functions cannot be used with yield keyword (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.

When to use arrow functions

  • Use function keyword to decare functions in a global scope, for generators, constructors and object methods.
  • Use function when you need to have an access to prototype
  • If you more OOP person use new class syntax with constructor keywords
  • Use arrow function in other cases
References
  1. https://developer.mozilla.org

Share:



Warning! This site uses cookies
By continuing to browse the site, you are agreeing to our use of cookies. Read our privacy policy