views:

262

answers:

9

Let's say I have var a = function() { return 1; }. Is it possible to alter a so that a() returns 2? Perhaps by editing a property of the a object, since every function is an object?

Update: Wow, thanks for all the responses. However, I'm afraid I wasn't looking to simply reassign a variable but actually edit an existing function. I am thinking along the lines of how you can combine partial functions in Scala to create a new PartialFunction. I am interested in writing something similar in Javascript and was thinking that the existing function could perhaps be updated, rather than creating an entirely new Function object.

+15  A: 
var a = function() { return 1; }
alert(a()) // 1
a = function() { return 2; }
alert(a()) // 2

technically, you're losing one function definition and replacing it with another.

Sam Hasler
12 upvotes. Congrats.
Martin
@martin heh, not bad for a minutes work. I feel kinda dirty.
Sam Hasler
A: 

Why would you not just assign a new function to a that returned 2?

Jonathan Bates
A: 

Found a Google link that might help: http://www.coryhudson.com/blog/2007/02/07/modify-existing-javascript-functions/

pagboy
A: 

Absolutely. Just assign to it a new function.

Mendy
This doesn't deserver a downvote. It may be terse, but it is absolutely correct.
Justin Johnson
A: 

Can you not just define it again later on? When you want the change try just redefining it as:

a = function() { return 2; }
Wayne Koorts
+1  A: 

If you're debugging javascript and want to see how changes to the code affects the page, you can use this Firefox extension to view/alter javascripts:

Execute JS firefox extension: https://addons.mozilla.org/en-US/firefox/addon/1729

Jon
+6  A: 

You can do all kinds of fun stuff with javascript, including redefining functions:

var a = function(){ return 1; }

alert(a()); //1

var old = a;
var a = function(){
  // call the original function, storing the result
  var originalResult = old.apply(a, arguments);
  // add one
  return originalResult + 1;
};
alert(a()); //2

Voila.

jvenema
+1 for redefining it in terms of the original function.
Sam Hasler
+1  A: 

How about this, without having to redefine the function:

var a = function() { return arguments.callee.value || 1; };
alert(a()); // => 1
a.value = 2;
alert(a()); // => 2
darkporter
+2  A: 

I used something like this to modify an existing function whose declaration was not accessible to me:

// declare function foo
var foo = function (a) { alert(a); };

// modify function foo
foo = new Function (
  "a",
  foo.toSource()
    .replace("alert(a)", "alert('function modified - ' + a)")
    .replace(/^function[^{]+{/i,"")  // remove everything up to and including the first curly bracket
    .replace(/}[^}]*$/i, "")  // remove last curly bracket and everything after<br>
);

Instead of toSource() you could probably use toString() to get a string containing the function's declaration. Some calls to replace() to prepare the string for use with the Function Constructor and to modify the function's source.

hmundt
Interesting. No way to do it without going through strings, though? Bummer.
pr1001