Siempre y cuando una función se trate como cualquier otra variable, se dice que ese lenguaje tiene first-class functions y JavaScript no iba a ser una excepción. En el caso de JavaScript las funciones son first-class objects ya que pueden ser almacenadas en una variable, un array y un objeto, pueden ser pasadas como argumentos a una función y pueden ser devueltas desde una función.

Almacenadas en una variable

// Variable
const diHola = function () {
  console.log('¡Hola!');
};

diHola(); // ¡Hola!

// Array
const saludos = [];
saludos.push(diHola);
console.log(saludos); // [function]
console.log(saludos[0]); // ¡Hola!

// Object
const saludo = { diHola };
console.log(saludo); // {diHola: function}
console.log(saludo.diHola()); // ¡Hola!

Pasadas como argumentos en una función

function diHola() {
  return 'Hola ';
}

function saludar(saludo, nombre) {
  console.log(saludo(), nombre); // Hola JavaScript
}

// Pasamos `diHola` como argumento de la función saludar
saludar(diHola, 'JavaScript');

Devueltas desde una función

function diHola() {
  return function () {
    console.log('¡Hola!');
  };
}

A una función que devuelve una función se le llama habitualmente higher-order function.

Para invocar a la función podemos hacerlo de dos maneras. Usando una variable o con doble paréntesis.

const saludar = diHola();
saludar(); // ¡Hola!
diHola()(); // ¡Hola!

Fuentes: