Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwrite and restore a function

I need to mock call a function in JavaScript. For this, I'm "saving" the function in a temporary variable, update the target with a new function block, calling the target and then restoring the old function:

var myObject = {
  myIntProp: 1,
  myFunc: function(value) {
    alert(value + 1);
  }
};
myObject.myFunc(2);

var tmp = myObject.myFunc;
myObject.myFunc = function(value) {
  alert(value - 1);
};
myObject.myFunc(2);

myObject.myFunc = tmp;
myObject.myFunc(2);

This works as expected: the function gets overwritten and then successfully restored. My thought was to move this code into a helper function and easily use it when needed:

function FunctionSwapper(target, newFunction) {
  var old = target;
  target = newFunction;
  this.Restore = function() {
    target = old;
  }
};

var myObject = {
  myIntProp: 1,
  myFunc: function(value) {
    alert(value + 1);
  }
};
myObject.myFunc(2);

var swapp = new FunctionSwapper(myObject.myFunc, function(value) {
  alert(value - 1);
});
myObject.myFunc(2);

swapp.Restore();
myObject.myFunc(2);

This code however, does not save the current state nor is it replacing the targeted function. What am I missing here? Isn't a function always passed as reference? What are the main differences between the two code snippets?

(JSFiddle available, but prepare for 8 alerts...)

Edit: a fellow user has pointed out that the second method does not really differ from the first one and that it's probably not worth the trouble of creating the additional class; while I do understand and agree with their arguments, I see two advantages in the second method (both apply to my particular, real-world case):

  1. it's easier/faster to write swapp.Restore(); than myNameSpace.level2.level3.level4.level5 = swap; when working with objects which have several levels of child elements and,
  2. it abstracts the operation, providing a consistent use among the development team (additionally, logging or type proofing could be done inside the class).
like image 208
Andrei V Avatar asked Jun 30 '15 11:06

Andrei V


People also ask

How to overwrite an existing database when doing a restore?

WITH REPLACE option allows you to overwrite an existing database when doing a restore. In some cases when you try to do a restore you may get an error that says "The tail of the log for the database .. has not been backed up".

What does the restore...with Replace option do?

The RESTORE ... WITH REPLACE option allows you to overwrite an existing database when doing a restore. In some cases when you try to do a restore you may get an error that says "The tail of the log for the database .. has not been backed up".

How do I restore an overwritten file?

On the menu tab, choose the "Previous Versions" button, then select the version you want to restore or the latest version of the file you have. That's it! Your overwritten file will be restored to you.

How do I overwrite the contents of a MySQL database?

Use the WITH REPLACE or WITH STOPAT clause of the RESTORE statement to just overwrite the contents of the log. RESTORE DATABASE is terminating abnormally.


1 Answers

This happens because target is not a true reference, it is a value which references target function.

However when you reassign target, you do not modify the held value (the reference to the function), but you modify the value directly, which means you can't do it this way.

Instead you can pass the object holding the function to replace (it would only work with an object, since you need to access it later).

Here is what I came up with

function FunctionSwapper(target, name, newFunction) {
  var old = target[name];
  target[name] = newFunction;
  this.Restore = function() {
    target[name] = old;
  }
};

var myObject = {
  myIntProp: 1,
  myFunc: function(value) {
    alert(value + 1);
  }
};
myObject.myFunc(2);

var swapp = new FunctionSwapper(myObject, 'myFunc', function(value) {
  alert(value - 1);
});
myObject.myFunc(2);

swapp.Restore();
myObject.myFunc(2);
like image 93
axelduch Avatar answered Oct 06 '22 19:10

axelduch