Reputation: 46833
In javascript, you can rewrite a function, like so:
function foo() {
setTimeout(function() {
alert('sup stallion');
foo = function() { //rewrite foo to nolonger wait 4 seconds to alert.
alert('sup stallion');
}
}, 4000);
}
Obviously this is a contrived example, but is there anything conceptually wrong with this approach (other than a race condition).
Upvotes: 7
Views: 1933
Reputation: 71918
One thing I noticed while testing your code. Consider this:
setInterval(foo, 6000);
Function foo
is being passed to setInterval
before it was modified, and the original foo
will run every 6 seconds, even after the binding has been updated.
On the other hand, the code below will run the original function only on the first call (which updates the binding). Subsequent calls will invoke the updated version:
setInterval(function(){foo();}, 6000);
Looks obvious, but could be hard to debug...
Upvotes: 4
Reputation: 179086
Dynamic function rewriting can be used as a form of lazy initialization, however there is a catch:
function Foo() {...}
Foo.prototype = {
bar: function () {
//some initialized variables to close over
var a, b, c, ...;
Foo.prototype.bar = function () {
//do stuff with variables
};
Foo.prototype.bar.call(this);
}
};
While this code is relatively straight-forward to understand, and would be used as:
var f = new Foo();
f.bar(); //initializes `bar` function
f.bar(); //uses initialized `bar` function
it has a hidden issue:
var f = new Foo(),
g = {};
//passing by reference before the function was initialized will behave poorly
g.bar = f.bar;
f.bar(); //initializes `bar` function
g.bar(); //re-initializes `bar` function
f.bar(); //uses initialized `bar` function
g.bar(); //re-initializes `bar` function
It's for this reason that any initialization needed for a function is typically done using a module pattern:
function Foo() {...}
Foo.prototype = {
bar: (function () {
var a, b, c, ..., fn;
//some initialized variables to close over
fn = function () {
//do stuff with variables
};
return fn;
}())
};
The module pattern has the disadvantage of calling the initialization code immediately, but wont have the issues associated with the function reference.
Upvotes: 3
Reputation: 700372
Self modifying code can be confusing, and hard to debug, so it's generally avoided.
Other than that there is no problem, and no race condition either.
Upvotes: 7