Základy Monkey Patchingu

Jako jeden z týmu MooTools a někdo, kdo roky pracoval se sadou nástrojů Dojo, jsem se rychle naučil jednu lekci: nikdy neupravíte zdroj knihovny, když ji používáte v dané webové aplikaci. Pokud tak učiníte, upgrady knihovny jsou noční můrou a obecná údržba je nemožná. Co tedy děláte, když čekáte, až tvůrci knihovny opraví svou chybu? Ty opičí náplast.

Co je tedy opičí záplatování? Je to proces nahrazení metod aktualizovanými, „opravujícími“ metodami pro originál. V tomto příkladu budeme předpokládat, že máme objekt s funkcí nazvanou setTransform . A co je na této ukázkové funkci špatného? Nastavuje styl CSS transform vlastnost, ale nenastavuje styl s předponou dodavatele, který vyžaduje několik prohlížečů. V tomto příkladu tento problém vyřešíme.

Prvním krokem v opičím záplatování je zachování odkazu na původní objekt (obvykle funkci):

var oldSetTransform = myLib.setTransform; /* function(element, transformValue) { element.transform = transformValue; } */

Uchováváme si odkaz na původní funkci, protože ji stále chceme spustit, prostě chceme přidat její funkčnost.

Dalším krokem v opičím záplatování metody je její nahrazení funkcí stejného jména na stejném objektu:

myLib.setTransform = function(element, transformValue) {
	/* new function body */
};

Díky této náhradní funkci přidané k novému objektu jej můžeme aktualizovat tak, aby plnil svůj původní účel, a také přidat kód pro předponu dodavatele:

var oldSetTransform = myLib.setTransform;

myLib.setTransform = function(element, transformValue) {
	element.webkitTransform = transformValue;
	element.mozTransform = transformValue;

	return oldSetTransform.apply(this, arguments);
};

S mým příkladem výše na umístění provedení původní funkce tolik nezáleží; pokud je přidán základní styl a styl s předponou dodavatele, je vše v pořádku.

Často je však důležité, v jakém pořadí se stará metoda a nové funkce používají.  Vezměme si další příklad – řekněme, že máme funkci, jejímž účelem je vypočítat daň z celkové částky objednávky, ale vláda nedávno přidala další 1 % daň z celkové částky za jakékoli kecy, za které chtějí příště utrácet peníze . Pojďme to udělat:

var oldGetTotal = myLib.getTotal;
myLib.getTotal = function() {
	var total = oldGetTotal.apply(this, arguments) + this.getTax();

	return total * 0.01;
};

U výše uvedené metody se k celkové objednávce plus daň přidá 1 % navíc. Ale co když chcete dát uživateli 20% slevu? Pak byste chtěli, aby byla sleva uplatněna před uplatněním daně:

var oldGetTotal = myLib.getTotal;
myLib.getTotal = function() {
	var total = oldGetTotal.apply(this, arguments) * 0.8;

	return total + this.getTax();
};

Podívejte se, jak důležitá může být pozice provedení původní funkce?

Monkey patching je základní dovedností pro každého pokročilého vývojáře JavaScriptu. Jako skutečný příklad můžete vidět, jak jsem po opici opravoval widget nabídky Dojo. Pokud chcete zlepšit své dovednosti JS, je důležité, abyste se naučili krásu opičího záplatování!