语言基础-猴子吃桃
As one of the MooTools team and someone who worked with the Dojo Toolkit for years, I quickly learned one lesson: you never modify the source of a library when using it on a given web app. Doing so makes upgrades of the library a nightmare and general maintenance impossible. So what do you do while you wait for the library creators to fix their bug? You monkey patch.
作为MooTools团队的一员,并且是使用Dojo Toolkit多年的人,我很快学到了一个教训:在给定的Web应用程序上使用库时,您永远不会修改库的源代码。 这样做会使升级磁带库成为一场噩梦,并且无法进行常规维护。 那么,在等待库创建者修复其错误时您会怎么做? 你这猴子补丁。
So what is monkey patching? It's the process of replacing methods with updated, "fixing" methods for the original. In this example we'll presume we have an object with a function called setTransform
. And what's wrong with this example function? It sets the style of the CSS transform
property but doesn't set the vendor-prefixed style required by a few browsers. In this example we'll fix that problem.
那么什么是猴子修补? 这是用原始的更新的“固定”方法替换方法的过程。 在此示例中,我们假设我们有一个对象,该对象具有一个名为setTransform
的函数。 这个示例函数怎么了? 它设置CSS transform
属性的样式,但不设置一些浏览器所需的供应商前缀样式。 在此示例中,我们将解决该问题。
The first step in monkey patching is keeping a reference to the original object (usually a function):
猴子修补的第一步是保留对原始对象(通常是函数)的引用:
var oldSetTransform = myLib.setTransform; /* function(element, transformValue) { element.transform = transformValue; } */
We keep a reference to the original function because we still want to execute it, we simply want to add to its functionality.
我们保留对原始函数的引用,因为我们仍要执行它,我们只是想添加其功能。
The next step in monkey patching the method is replacing it with a function of the same name on the same object:
猴子修补方法的下一步是在同一对象上用相同名称的函数替换该方法:
myLib.setTransform = function(element, transformValue) {
/* new function body */
};
With this replacement function added to the new object, we can update it so that it executes its original purpose as well as adds code to do the vendor prefixing:
通过将此替换函数添加到新对象中,我们可以对其进行更新,使其执行其原始用途,并添加代码以进行供应商前缀:
var oldSetTransform = myLib.setTransform;
myLib.setTransform = function(element, transformValue) {
element.webkitTransform = transformValue;
element.mozTransform = transformValue;
return oldSetTransform.apply(this, arguments);
};
With my example above, the placement of the original function's execution doesn't matter all that much; as long as the base style and vendor prefixed style are added, things are good.
在上面的例子中,原始函数执行的位置并不重要。 只要添加基本样式和供应商前缀样式,就可以了。
Oftentimes, however, it's important which order the old method and new functionality are run in. Let's take another example -- let's say we have a function whose purpose is calculating the tax on an order's total, but the government recently added an additional 1% tax on the total for whatever bullshit they want to waste money on next. Let's make that happen:
但是,通常情况下,运行旧方法和新功能的顺序很重要。再举一个例子-假设我们有一个函数,其目的是计算订单总额的税金,但政府最近又增加了1%总税 不管他们想浪费什么废话 。 让我们做到这一点:
var oldGetTotal = myLib.getTotal;
myLib.getTotal = function() {
var total = oldGetTotal.apply(this, arguments) + this.getTax();
return total * 0.01;
};
With the method above, an extra 1% is added on top of the order total plus tax. But what if you want to give the user a 20% discount? Then you'd want the discount applied before the tax is applied:
使用上述方法,在订单总额加税额的基础上再增加1%。 但是,如果您想给用户20%的折扣呢? 然后,您希望在应用税之前应用折扣:
var oldGetTotal = myLib.getTotal;
myLib.getTotal = function() {
var total = oldGetTotal.apply(this, arguments) * 0.8;
return total + this.getTax();
};
See how important the position of the original functionality execution can be?
看看原始功能执行的地位有多重要?
Monkey patching is an essential skill for any advanced JavaScript developer. You can see how I monkey patched Dojo's menu widget as a real example. If you're looking to level up your JS skills, it's important you learn the beauty of monkey patching!
对于任何高级JavaScript开发人员而言,猴子修补都是一项必不可少的技能。 您可以看到我如何修补Dojo的菜单小部件作为一个真实示例。 如果您想提高自己的JS技能,那么一定要学习猴子修补的美!
语言基础-猴子吃桃