Simples: uma função é um objeto como qualquer outro, e como tal, pode ter métodos “acoplados” a ela.
Mas vamos por partes. Primeiro, um objeto qualquer pode ter uma função acoplada a ele:
// um objeto qualquer
let obj = { id: 1, nome: 'Fulano' };
// definir uma propriedade que é uma função
obj.funcao = function() { console.log('oi') };
// chamar a função
obj.funcao(); // oi
Segundo a documentação, funções também são objetos (“Every JavaScript function is actually a Function object”). Então nada impede que eu faça a mesma coisa com uma função:
function Abc() {
// função que faz algo...
}
Abc.fazOutraCoisa = function(n) {
console.log(n);
}
Abc.fazOutraCoisa(20); // 20
console.log(typeof Abc); // function
// repare que "fazOutraCoisa" aparece como uma das propriedades de Abc
console.log(Object.getOwnPropertyNames(Abc)); // [ 'length', 'name', 'arguments', 'caller', 'prototype', 'fazOutraCoisa' ]
Repare que não preciso criar uma instância de Abc para usar a função fazOutraCoisa. Pois ela é uma propriedade da própria função Abc. No fundo, isso é uma forma de simular os métodos estáticos de outras linguagens.
Foi falado sobre o class e static para criar o “método estático”. Mas no fundo isso é só um açúcar sintático (uma forma mais “simples/elegante” de se criar a mesma coisa). Pois no fundo, não existem classes de fato no JavaScript, já que o class é no fundo uma outra forma de se criar uma função construtora:
class Abc {
static fazOutraCoisa(n) {
console.log(n);
}
}
console.log(typeof Abc); // function
console.log(Object.getOwnPropertyNames(Abc)); // [ 'length', 'name', 'prototype', 'fazOutraCoisa' ]