JS扩展方法的功能
JS extend functionality of a method
我正在尝试扩展 2dcontext 对象某些方法的功能,但是我无法让它按照我想要的方式工作:我想重写一个方法,但我想从被覆盖的方法调用原始方法,如下所示:
//First get the original context
var ctx = canvas.getContext("2d");
//Create a class which uses ctx as it's prototype
var ExtendedContext = function (){};
ExtendedContext.prototype = ctx;
//And extend a method
ExtendedContext.prototype.fillRect = function(x, y, width, height) {
//Do some stuff
this.prototype.fillRect(x, y, width, height); //Doesn't work
//Do some more stuff
};
如何从自己的方法内部调用原始fillRect
方法?
您可以像这样存储原始函数的引用:
var oldFillRect = ctx.fillRect;
然后像这样称呼它
ExtendedContext.prototype.fillRect = function() {
//Do some stuff
oldFillRect.apply(this, arguments);
//Do some more stuff
};
这种技术有时被称为"鸭子打孔"或"功能钩"。在此特定实例中,还应能够使用 Object.getPrototypeOf
方法来获取原始函数引用。这看起来像
ExtendedContext.prototype.fillRect = function() {
//Do some stuff
Object.getPrototypeOf(ExtendedContext.prototype).fillRect.apply(this, arguments);
//Do some more stuff
};
因此,您甚至不需要存储引用。
无需将旧名称保存在单独的对象中,请使用闭包:
ExtendedContext.prototype.fillRect = (function () {
var oldf = ExtendedContext.prototype.fillRect;
return function () {
//Do some stuff
oldf.apply (this, arguments);
//Do some more stuff
};
}) ();
如果你有一堆这样做可能会有所帮助:
function extend (fnc) {
var mthd = (fnc.toString ().match (/^function's+('w+)'s*'(/) || ['', ''])[1];
if (mthd in ExtendedContext.prototype)
throw ('ExtendContext method ' + mthd + 'does not exist');
ExtendedContext.prototype['_' + mthd] = ExtendedContext.prototype[mthd];
ExtendedContext.prototype[mthd] = fnc;
}
然后你可以按如下方式调用扩展
extend (function fillrect () {
// Do some stuff
this._fillrect.apply (this, arguments);
// Do some more stuff
});
要引用旧方法,请使用其名称前缀为"_">
我迟到了几个月,但我正在使用一个相当简单的设计来完成这个功能。我们的 JavaScript 结构从一个全局对象运行,以保护我们的代码免受全局变量的影响。
对于每个页面/用户控件,我们正在修改全局对象以保存一个新对象,但某些代码在不同的地方需要不同的功能,需要扩展方法。我们不想复制代码并重新定义扩展实例的整个对象,也不想让代码关心它的扩展方式。
与其打鸭子,直到它做你想做的事,为什么不创建一个通用的扩展方法呢?使用我们的案例,这里有一个例子:
// Using a Global JavaScript object:
GlobalNameSpace.ExtensionFunction = function(oParam1, oParam2, oParam3)
{
/// <summary>All parameters are optional</summary>
return; // For instances when it is not being overwritten, simply return
}
//In the Code to be extended:
GlobalNameSpace.Control.ControlFunction(oSender, oArgs)
{
///<summary>Control's function</summary>
// Function-y stuff..
GlobalNameSpace.ExtensionFunction(oSender, oArgs);
}
//and finally in the code to extend the functionality
GlobalNameSpace.Page.Init
{
///<summary>Initializes the page</summary>
// redefine the extension function:
GlobalNameSpace.ExtensionFunction = function(oSender, oArgs)
{
// Call the extension function, or just code the extension here
GlobalNameSpace.Page.Function(oSender, oArgs);
}
}
此方法的缺点是,如果要一次对多个对象执行此操作,此时将扩展方法移动到您特别想要扩展的代码中可能是一个更好的主意。这样做将使该扩展代码不那么通用,但这可以根据您的需要决定。
相关文章:
- 有没有一种方法可以修改在使用javascript的媒体功能的媒体查询下创建的样式
- 使用多功能框在 chrome 扩展程序中包含内联自动填充功能的任何方法
- 基本阵列构造的功能方法
- AngularJS控制器之间共享代码/方法/功能
- 制作预制响应功能的最佳方法是什么
- 在触摸屏上实现<缩写>型功能的最干净方法
- 自动排序方法以附加功能
- 识别浏览器 HTML5 功能的推荐方法
- 将javascript方法功能分组到javascript“类”中
- 使用无状态功能组件与调用方法有什么区别
- JS扩展方法的功能
- javascript:在页面加载后执行该功能的最佳方法
- 通过SWT浏览器/ SWT浏览器功能从GWT应用程序调用Java方法
- 处理所需和可选功能参数的推荐方法
- 调用自定义API方法的功能
- 有没有更有效的方法来处理重复的功能
- 这是对象方法的内在功能
- 编辑JSON对象-寻找更好的功能方法
- 将对象简化为字符串的功能方法
- 从对象数组上的属性创建数组的功能方法