I'm not interested in call or apply to change the this
reference. Just for my own interest, I'm playing with an idea for another require technique for javascript that would make for some cleaner definitions, and the goal was to not have to pass arrays or doubly reference module names for my definitions.
I have a sample solution (just a proof of concept) using toString and eval on a function but I'm wondering if there is a safer or more efficient way to do this.
// Sample module libraries (would probably be in their own files)
someModules = {
testModule: {test: function(){console.log("test from someModule")}},
anotherModule: { doStuff: function(){console.log("Doin stuffs!");}}
};
sampleRequire = function() {
// Load the modules
for (var i=arguments.length-2; i>=0; --i){
// Create a local variable reference to the module
eval ('var '+arguments[i]+' = someModules.'+arguments[i].toString());
}
// Redefine the programmer's function so that it has my local vars in its scope
eval("var fn = "+arguments[arguments.length-1]);
return fn;
}
// Main code...
sampleRequire( 'testModule', 'anotherModule',
function(){
testModule.test();
anotherModule.doStuff();
}
)();
Edit:
Pointy made an excellent point that this would completely destroy the main function's scope, which would often times be unacceptable. Ideally I'd like to see the module variables being added to the function's scope without clobbering its other scoped variables (with the exception of the module names--the programmer must know not to use the same name for two things). I'm betting this is probably impossible, but I would still love to see some ideas.
Another goal is to do this flexibly without having to add arguments per module to the main function. Otherwise we're back to square one with CommonJS styles (which I'm not trying to fight, just curious about scope!).
How about something like:
I tend to say "you're doing it wrong". Using undeclared variables is never a good idea, even though you can.
Here's another hack which writes the modules to the global object. However, this may have side effects on the methods called from the main function.
I also tried some magic with the
with
keyword, which was basically made for precisely what you want. However, it looks like it doesn't work withouteval
in this case.I can't think of any other way of doing what you're after. I also suspect this may be one of the few use cases of
eval
that is not evil. But do keep in mind that the modules could rely on their scopes and this could break them.