views:

60

answers:

2

Hi all,

Suppose I had the following function:

function alertMesg()
{
   alert("This ok function alerts message!");
}

Now at run time I would like to change the alertMesg function to do something else. My thought was to do somehting like this.

var temp = window.alertMesg.toString.replace("ok","great")
temp = temp.replace('function alertMesg()',"");
window.alertMesg = new Function(temp);

Basically, the problem is I have no control over the source in the alertMesg function. I would like change the function, but I can't actually change the source of it. Because it is produced server side. That being said I need it to act differently.

Thanks, Grae

PS: I forgot to mention an important part. I have to keep most of the function. I can't just replace the function out right. I have to keep 95% of the function the way it is, and change the other five percent.

@Barlow Tucker, quixoto, pekka Thanks, for the interest.

Basically, I don't think the proxy idea will work because I am not just adding functionallity, I am changing the functionallity of the code. I want for example, the third line of the function to be different. In my real life example I have to add a line right in the middle of a function.

A: 

If you must replace the content of a function, it is possible:

function alertMesg()
{
   alert ("This ok function alerts my message!");
}

alertMesg(); // alerts "This ok function alerts my message!"

// do whatever you want to the function here
var temp = alertMesg.toString();
temp = temp.replace('my', 'your');

// now replace the original function
alertMesg=new Function(temp.substring(temp.indexOf('{')+1,temp.lastIndexOf('}')));

alertMesg(); // alerts "This ok function alerts your message!"

This probably isn't the best way to do what you're trying to achieve, but I can't really suggest anything else unless you provide more details.

Dumb Guy
I followed at first, but you lost me at the eval. Just calling eval on temp magically changes alertMesg? I tried your source on IE, and got a JavaScript Error.
Grae
Hmm...if your function is defined as alertMesg = function(), then you might have to use `alertMesg = eval('('+temp+')');` instead.
Dumb Guy
Now, I get an object expected error, on the final alertMesg() call.
Grae
How about `alertMesg = new Function(temp.substring(temp.indexOf('{')+1,temp.lastIndexOf('}')));`
Dumb Guy
It worked! Thank you! You saved me a lot of trouble!!! The reason I needed to do this was because the catch() in the JSF produced JavaScript code catches exceptions in my functions, so if there is a JavaScript error in my code, it crashes parts of the produced code without letting me know. It was a real pain trying to guess what was wrong. I am going to overwrite the catch, and put some of my own code in there. At least, now I will know right away when I crash their code. Rather, than various peaces of the web just not working.
Grae
Thanks, for your help. The problem really was a pain, hopefully this will make things a bit easier.
Grae
+3  A: 

Dynamic code replacement like you're suggesting might work in some cases, but it's a scary road to go down-- fragile, one wrong step and you're busted, and it quickly becomes a maintenance nightmare.

As a commenter said, your cleaner bet is to just wrap the native window.alert and then do the right thing when the string you care about comes through, per the answer here: http://stackoverflow.com/questions/1729501/javascript-overriding-alert

(Insert standard comment here about how you should get your server side people on the same page/team as you on this so you don't need to hack around your own page.)

UPDATE: You're not asking about alert, you're asking about this problem generally. Yes, you could what others are suggesting. But if you have the original code for the function, why not just replace it entirely? If the function you want is a global function called foo(), you can run JS that does:

window.foo = function() {
    // The stuff I know is there (A)
    ...
    // Some new stuff I want to change (B)
    ...
    // More stuff I know is there (C)
}

Which will throw away the original and replace it with your version. This would work reasonably well, although "monkey patching" the stuff in the page definitely comes with some maintenance headaches.

I will definitely note here that if you can't do this for some reason and thus insist on doing textual code replacement in the middle of existing functions, you're abusing the language/environment for the purposes of maintainable anything, and you are truly screwed in multiple ways.

quixoto
Suppose the original function has part a, part b, and part c. I want the new function to have part a, part b, a new part, and then part c. With the overwriting, I can only have the new function be like new part, part a, part b, part c, or like part a, part b, part c, and then the new part. Unless I am not understanding, the new part I am adding, can not be in the middle of the function with you idea.
Grae
I need to add some code to the middle of the function, not the start or end of it. However, thank you, for trying.
Grae
The JavaScript function I have to modify is dynamically produced by JSF, server side, and is different on every page. I really need a solution that lets me modify the existing function, because I don't really know what will be in the function ahead of time. It basically follows a pattern, and I know what I need to change each time, but I don't know all the stuff in the function ahead of area I want to change. I do think I can guess all the stuff after that point, if that helps.
Grae