So I ran into another issue the other day. I needed to create a function that could be overwritten, then have any reference to the original point to the new one… without redoing everything again… For example:
funk = function() { alert('original'); }
caller = funk;
funk = function() { alert('new'); }
// this will alert 'original'... Not 'new';
caller();
But what if I want to be able to override functions and have those such as “caller” mentioned above, to point to the new function. Such an example would be where the function could be overridden based on what modules are loaded and what are not. But the original function will always be referenced. There is a solution though. It takes a little bit more plus my code below. But it is possible now.
By using funcStorage.js, you can use this code for appending functions, or referencing functions by name instead of their location in memory. Essentially you can run the caller() function and have it execute whatever happens to be associated with that at the time, not what it was when it was originally assigned.
Lets attempt something that’s not just pseudo code. Our issue is we want to reload a custom made file directory. The easiest way is to do a window.location.reload(); call. Lets set that as our reloadFileList() = function() { window.location.reload(); }. But we want to use a fancy AJAX solution. In this case we want to just override the function as the AJAX solution is much better. We can’t just go reloadFileList = ajaxReload; because any function that already references reloadFileList will point to the original window.reload one.
Now let me be clear here:
// I do not mean this.
element.onclick = function() { reloadFileList(); }
// I DO mean this!
element.onclick = reloadFileList;
So the only way before was to go back to all the previous references used for reloadFileList and reassign it the new function. But now with the code I posted, you can do the following.
// You can specify what function the onclick uses
// before it's even created.
element.onclick = funcStorage.call('reloadFileList');
funcStorage.create('reloadFileList', function() { window.location.reload(); });
// Later on, or in another file...
funcStorage.create('reloadFileList', function() {
fileList = getFileList_viaAJAX('url/here');
for( k in fileList) {
// perform actions
}
});
So without redefining the element.onclick, it now uses the new Ajax style instead of the window.reload.
For me, the primary reason is for letting the site function even if the file didn’t download properly, I had a bug in one of my js files, or the user aborted while it was getting another file. I would like the site to still work, even if not completely as intended… essentially graceful degradation or a fault-tolerant system.
There’s more than just this, the class also allows for extending functions instead of just overriding them. If you use the extend method instead of the create, whatever is already defined as the function you want, it will get appended with the section argument.
// You don't need to initialize anything.
// Any call, create, or extend will create the necessary
// elements before they are used.
funcStorage.extend('reloadFileList', function() { // ajax style reload });
// now lets put tooltips with thumbnails on the various files...
funcStorage.extend('reloadFileList', function() {
// the down side is you have to treat each extension as if
// it's its own environment and doesn't have access to the variables
// from the previous extensions.
$(elements).each( function() {
// assign a tooltip with picture inside.
});
});
This will then run both functions sequentially. After doing the Ajax call, it will do the tooltip generation.
Hopefully someone else finds this useful.
Again, it’s: funcStorage.js