I am trying to implement (so-to-say) a refinement in JavaScript. Kindly look at the following example:
<html>
<head>
<title>Function Override (Refinement) example</title>
<script type="text/javascript">
// original function
function oneFunc() {
document.writeln("<p> In original oneFunc() </p>");
}
var prevOneFunc = null;
if (oneFunc) {
prevOneFunc = oneFunc;
}
// redeclared function (should refine/complement the original one)
function oneFunc() {
if (prevOneFunc) {
prevOneFunc(); // should call original oneFunc(), BUT IT ISN'T
}
document.writeln("<p> In refined oneFunc() </p>");
}
oneFunc();
</script>
</head>
<body>
</body>
</html>
My intention was to have two printouts:
In origina开发者_如何转开发l oneFunc() In refined oneFunc()
However, it seems that since at the moment of execution oneFunc
refers to the new/refined function, hence the output is different than expected. In the debugger checked that I am entering into the infinite recursion :) (yes, understood why exactly).
Please explain which information I am missing to implement it properly.
Update: A few limitations: I think (not sure) that I can't modify the original oneFunc
declaration and it is declared just like described above. I shouldn't modify the declaration of the refined oneFunc
either.
This works: http://jsfiddle.net/maniator/gxpK8/
When you do it your way you are defining:
prevOneFunc = function oneFunc(){...}
So you are not assigning a anonymous function, therefore to do what you want to do you have to declare oneFunc
like so:
oneFunc = function() {
document.writeln("<p> In original oneFunc() </p>");
}
Then later on it is correct:
prevOneFunc = function(){...}
I would use a closure. It avoids (another) global property and shows intent better, at least to me.
// original function
function oneFunc() {
return "world"
}
alert(oneFunc)
oneFunc = (function (original) {
// a closure will prevent the original function -- which is an object
// from ever being lost
return function () {
alert("before");
var ret = original()
alert("after")
return "hello " + ret
}
})(oneFunc)
alert(oneFunc)
Happy coding
For comment:
The exact same applies. Functions are just objects. The only "trick" is making sure someone else calls your object. If the function is a property (as in the code shown) then it's easy:
window.somefunc = myfunc
someobj.somefunc = myfunc
The only case when it's not easy (really possible) is when the function has been bound in some for of closure or otherwise accessed via a different mechanism.
http://jsfiddle.net/tylermwashburn/6Fu8Q/
That should do what you want. :)
That is because of JavaScript hoisting. http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Try this:
var oneFunc = function(){
//In original oneFunc
};
var prevOneFunc = null;
if (oneFunc) {
prevOneFunc = oneFunc;
}
oneFunc = function(){
//In refined oneFunc
};
oneFunc();
精彩评论