The main reason why I want it is that I want to extend my initialize function.
Something like this:
// main.js window.onload = init(); function init(){ doSomething(); } // extend.js function extends init(){ doSomethingHereToo(); }
So I want to extend a function like I extend a class in PHP.
And I would like to extend it from other files too, so for example I have the original init function in main.js
and the extended function in extended.js
.
If you're assigning these functions to some property somewhere, you can wrap the original function and put your replacement on the property instead: // Original code in main. js var theProperty = init; function init(){ doSomething(); } // Extending it by replacing and wrapping, in extended.
The extends keyword can be used to extend the objects as well as classes in JavaScript. It is usually used to create a class which is child of another class. Syntax: class childclass extends parentclass {...}
To "extend f", means to define a function g, whose domain contains the domain of f, such that g(x)=f(x) for all x in the domain of f.
With a wider view of what you're actually trying to do and the context in which you're doing it, I'm sure we could give you a better answer than the literal answer to your question.
But here's a literal answer:
If you're assigning these functions to some property somewhere, you can wrap the original function and put your replacement on the property instead:
// Original code in main.js var theProperty = init; function init(){ doSomething(); } // Extending it by replacing and wrapping, in extended.js theProperty = (function(old) { function extendsInit() { old(); doSomething(); } return extendsInit; })(theProperty);
If your functions aren't already on an object, you'd probably want to put them there to facilitate the above. For instance:
// In main.js var MyLibrary = { init: function init() { } }; // In extended.js (function() { var oldInit = MyLibrary.init; MyLibrary.init = extendedInit; function extendedInit() { oldInit.call(MyLibrary); // Use #call in case `init` uses `this` doSomething(); } })();
But there are better ways to do that. Like for instance, providing a means of registering init
functions.
// In main.js var MyLibrary = (function() { var initFunctions = []; return { init: function init() { var fns = initFunctions; initFunctions = undefined; for (var index = 0; index < fns.length; ++index) { try { fns[index](); } catch (e) { } } }, addInitFunction: function addInitFunction(fn) { if (initFunctions) { // Init hasn't run yet, remember it initFunctions.push(fn); } else { // `init` has already run, call it almost immediately // but *asynchronously* (so the caller never sees the // call synchronously) setTimeout(fn, 0); } } }; })();
Here in 2020 (or really any time after ~2016), that can be written a bit more compactly:
// In main.js const MyLibrary = (() => { let initFunctions = []; return { init() { const fns = initFunctions; initFunctions = undefined; for (const fn of fns) { try { fn(); } catch (e) { } } }, addInitFunction(fn) { if (initFunctions) { // Init hasn't run yet, remember it initFunctions.push(fn); } else { // `init` has already run, call it almost immediately // but *asynchronously* (so the caller never sees the // call synchronously) setTimeout(fn, 0); // Or: `Promise.resolve().then(() => fn());` // (Not `.then(fn)` just to avoid passing it an argument) } } }; })();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With