arrow vs regular function

Differences

  1. Inside a regular function, the this value is dynamic. It depends on how the function is invoked.
    const person = {
        firstName: '',
        lastName: '',
        getFullName: function() {
            return `${this.firstName} ${this.lastName}`;
        },
    };
    
    person.firtName = 'Foo';
    person.lastName = 'Bar';
    person.getFullName();       // 'Foo Bar'
    Arrow function does not have this. Accessing this inside an arrow function will refer to the this of its closest non-arrow parent function.
    const person = {
        yearOfBirth: new Date().getFullYear(),
        getAge: () => {
            return new Date().getFullYear() - this.yearOfBirth;
        },
    };
    
    person.yearOfBirth = 2000
    person.getAge();            // NaN
    It is worth noting that calling arrowFunction.call(thisValue) or arrowFunction.apply(thisValue) do not change the this value.
  2. We can use the new keyword with a regular function to create new object.
    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    
    const foo = new Person('Foo', 42);
    On the other side, arrow functions do not own this value, hence they cannot be invoked with the new keyword.
    const person = (name, age) => {...}
    
    // ERROR: person is not a constructor
    const foo = new person('Foo', 42);
  3. Inside a regular function, we can use arguments which represents an array-like object of passed arguments. It is very useful if we want to access the parameters of a function whose number of parameters are dynamic.
    For example, the function below calculate the average of parameters:
    function average() {
        const args = [...arguments];
        return args.reduce((a, b) => a + b) / args.length;
    }
    
    average(1, 2);      // 1.5
    average(1, 2, 3);   // 2
    Arrow functions do not have arguments. Calling arguments inside an arrow function will return the arguments of closest non-arrow parent function.
    But it is still possible to get the list of dynamic passed parameters by using the rest parameters
    const average = (...args) => args.reduce((a, b) => a + b) / args.length;
    
    average(1, 2, 3, 4);        // 2.5
    average(1, 2, 3, 4, 5);     // 3
  4. We have to use the return statement in a regular function to return a result.
    function sum(a, b) {
        return a + b;
    }
    However, in an inline arrow function that contains only one expression, we can implicitly return the value by omitting the curly brackets. The sum function above can be rewritten as follow:
    const sum = (a, b) => a + b;
    Plus, arrow function also does not require parentheses if it has only one parameter:
    const sumOfArray = arr => arr.reduce((a, b) => a + b, 0);
  5. In non-restrict mode, regular functions allow us to use duplicate named parameters.
    The following declaration is accepted:
    function double(x, x) {
        return x + x;
    }
    
    double(3, 2);   // 4 
    double(3, 5);   // 10
    This usage is not allowed in strict mode:
    'use strict';
    function double(x, x) { ... }
    
    // ERROR: Duplicate parameter name not allowed
    It is not possible to use the same name for different parameters in arrow functions, no matter the strict or non-strict mode is enabled.

Good practice

If the inline arrow function consists of the <, <=, > or >= operator, it is advised to wrap the function body in parentheses.
Looking at the two versions below, it is easy for the first variant to cause a misleading.
// Bad
const compareToZero = a => a <= 0 ? 0 : a;

// Good
const compareToZero = a => (a <= 0 ? 0 : a);

Tip

You can use an underscore to name the argument which is not used in an arrow function. It makes the code more readable.
// No arguments
const noop = _ => {};

const range = (min, max) => Array(max - min + 1).fill(0).map((_, i) => min + i);

Resource

You can find many useful arrow functions that have only single line of code at https://1loc.dev
Hit the Subscribe button for the latest news on my tools. No spam. Ever!
© 2020 Nguyen Huu Phuoc. All rights reserved