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!