Here's my solution. It:
- uses regular modern classes and
.bind()
ing, no prototype
. (EDIT: Actually, see the comments for more on this, it may not be desirable.)
- works with modules. (I'll show an alternative option if you don't use modules.)
- supports easy conversion from existing code.
- yields no concern for function order (if you do it right).
- yields easy to read code.
- is low maintenance.
- unfortunately does not play well with static functions in the same class, you'll need to split those off.
First, place this in a globals file or as the first <script>
tag etc.:
BindToClass(functionsObject, thisClass) {
for (let [ functionKey, functionValue ] of Object.entries(functionsObject)) {
thisClass[functionKey] = functionValue.bind(thisClass);
}
}
This loops through an object and assigns and binds each function, in that object, by its name, to the class. It .bind()
's it for the this
context, so it's like it was in the class to begin with.
Then extract your function(s) from your class into a separate file like:
//Use this if you're using NodeJS/Webpack. If you're using regular modules,
//use `export` or `export default` instead of `module.exports`.
//If you're not using modules at all, you'll need to map this to some global
//variable or singleton class/object.
module.exports = {
myFunction: function() {
//...
},
myOtherFunction: function() {
//...
}
};
Finally, require the separate file and call BindToClass
like this in the constructor() {}
function of the class, before any other code that might rely upon these split off functions:
//If not using modules, use your global variable or singleton class/object instead.
let splitFunctions = require('./SplitFunctions');
class MySplitClass {
constructor() {
BindToClass(splitFunctions, this);
}
}
Then the rest of your code remains the same as it would if those functions were in the class to begin with:
let msc = new MySplitClass();
msc.myFunction();
msc.myOtherFunction();
Likewise, since nothing happens until the functions are actually called, as long as BindToClass()
is called first, there's no need to worry about function order. Each function, inside and outside of the class file, can still access any property or function within the class, as usual.