JS extends the functionality of the method

I am trying to extend the functionality of some methods of a 2dcontext object, but I cannot make it work the way I want: I want to override the method, but I want to call the original method from the overridden method:

//First get the original context
var ctx = canvas.getContext("2d");

//Create a class which uses ctx as it 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
};

How can I call the original method fillRectfrom my own method?

+3
source share
3 answers

You can save the link to the original function like this:

var oldFillRect = ctx.fillRect;

and then name it like

ExtendedContext.prototype.fillRect = function() {
    //Do some stuff
    oldFillRect.apply(this, arguments);
    //Do some more stuff
};

This technique is sometimes called duck ducking or hook function. In this particular case, you can also use the method Object.getPrototypeOfto get the original reference to the function. It will look like

ExtendedContext.prototype.fillRect = function() {
    //Do some stuff
    Object.getPrototypeOf(ExtendedContext.prototype).fillRect.apply(this, arguments);
    //Do some more stuff
};

Therefore, you do not even need to store the link.

+3
source

, :

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
});

, '_'

+1

, . JavaScript , vars.

/usercontrol , , . , , , .

Instead of punching a duck until it does what you want, why not create a common extension method? Using our case, here is an example:

// 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 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); 
    }
}

The short jump to this method is that you want to do this for several objects at a time, and at this point it might be better to move the extension method to the code that you specifically want to extend. This will make the extension code less general, but it can be solved according to your needs.

0
source

All Articles