Como um dos MooTools e alguém que trabalhou com a equipe do Kit de ferramentas Dojo durante anos, aprendi rapidamente uma lição: nunca modifique o código-fonte de uma biblioteca ao usá-la em um determinado aplicativo da Web. Fazer isso torna as atualizações da biblioteca um pesadelo e a manutenção geral impossível. Então, o que o senhor faz enquanto espera que os criadores da biblioteca corrijam o erro? O senhor faz um “monkey patch”.
Então, o que é monkey patching? É o processo de substituição de métodos por métodos atualizados, “corrigindo” os métodos originais. Neste exemplo, vamos supor que temos um objeto com uma função chamada setTransform
. E o que há de errado com essa função de exemplo? Ela define o estilo do CSS transform
mas não define o estilo prefixado pelo fornecedor exigido por alguns navegadores. Neste exemplo, vamos corrigir esse problema.
A primeira etapa do monkey patching é manter uma referência ao objeto original (geralmente uma função):
var oldSetTransform = myLib.setTransform; /* function(element, transformValue) { element.transform = transformValue; } */
Mantemos uma referência à função original porque ainda queremos executá-la, simplesmente queremos adicionar à sua funcionalidade.
A próxima etapa da correção do método monkey é substituí-lo por uma função com o mesmo nome no mesmo objeto:
myLib.setTransform = function(element, transformValue) { /* new function body */ };
Com essa função de substituição adicionada ao novo objeto, podemos atualizá-lo para que ele execute sua finalidade original, além de adicionar código para fazer a prefixação do fornecedor:
var oldSetTransform = myLib.setTransform; myLib.setTransform = function(element, transformValue) { element.webkitTransform = transformValue; element.mozTransform = transformValue; return oldSetTransform.apply(this, arguments); };
No meu exemplo acima, o posicionamento da execução da função original não importa muito; contanto que o estilo base e o estilo prefixado do fornecedor sejam adicionados, tudo estará bem.
Muitas vezes, no entanto, é importante saber em que ordem o método antigo e a nova funcionalidade são executados. Vejamos outro exemplo: digamos que temos uma função cujo objetivo é calcular o imposto sobre o total de um pedido, mas o governo recentemente acrescentou um imposto adicional de 1% sobre o total para qualquer besteira que eles queiram desperdiçar dinheiro em seguida. Vamos fazer isso acontecer:
var oldGetTotal = myLib.getTotal; myLib.getTotal = function() { var total = oldGetTotal.apply(this, arguments) + this.getTax(); return total * 0.01; };
Com o método acima, um adicional de 1% é adicionado ao total do pedido mais impostos. Mas e se o senhor quiser dar ao usuário um desconto de 20%? Então o senhor quer que o desconto seja aplicado antes da aplicação do imposto:
var oldGetTotal = myLib.getTotal; myLib.getTotal = function() { var total = oldGetTotal.apply(this, arguments) * 0.8; return total + this.getTax(); };
O senhor está vendo como a posição da execução da funcionalidade original pode ser importante?
O monkey patching é uma habilidade essencial para qualquer desenvolvedor JavaScript avançado. O senhor pode ver como fiz o monkey patch no widget de menu do Dojo como um exemplo real. Se quiser aprimorar suas habilidades em JS, é importante que aprenda a beleza do monkey patching!