JavaScript–Singleton Pattern

Desing Patterns & JavaScript

O Singleton Pattern diz que você pode ter apenas uma única instância de uma classe (ou, no caso do JavaScript, função construtora). Isso significa que uma vez que a classe for instanciada, você deve sempre retornar esta mesma instância em chamadas subsequentes.

Um exemplo clássico deste pattern é usar um único objeto como namespace de sua aplicação, como podemos ver no exemplo abaixo:


var MinhaApp = {};

Pelo fato de termos definido a variável como um objeto, não podemos instanciar novos objetos à partir dele (embora possamos criar novos objetos usando este como base com a função Object.create, por exemplo).

Esse pattern também pode ser aplicado às funções construtoras. A maneira mais simples é utilizar Singleton com Immediately-Invoked Function Expression (IIFE) ou, como dizemos mais comumente, funções auto-executáveis.


function MinhaApp() {
    if (!MinhaApp.instance) {
    MinhaApp.instance = this;
    }
    return MinhaApp.instance;
}

Essa função construtora irá garantir que você sempre receba a mesma instância como resultado. Isso só é possível porque funções construtoras utilizam o retorno como resultado da instanciação. Na prática, você poderia retornar qualquer tipo de objeto, como arrays ou strings.


var instance = new MinhaApp();
console.log(instance === new MinhaApp()); // result = true

Você pode perceber que o resultado é sempre o mesmo, independente de quantas vezes instanciarmos a função MinhaApp.

O grande problema dessa implementação é que alguém pode manipular a instância armazenada em MinhaApp.instance, embora seja pouco provável. Uma alternativa seria utilizar o conceito de closure para simular a privacidade do atributo.


function MinhaApp() {
    var instance;

    MinhaApp = function () {
    return instance;
    };

    instance = this;
}

Essa é uma implementação bastante curiosa. A função MinhaApp possui uma implementação que redefine a própria função MinhaApp para retornar apenas a instância.

Alternativamente você poderia utilizar o Module Pattern, mas acho que fica um pouco mais complexo que a implementação anterior.


var MinhaApp;

(function () {
    var instance;

    MinhaApp = function () {
    if (instance) {
    return instance;
    }

    instance = this;
    };
})();

Bons estudos e até a próxima galera!


Author's profile picture

Vitor is a computer scientist who is passionate about creating software that will positively change the world we live in.

MVP Azure - Cloud Architect - Data science enthusiast


2 minutes to read