0

I want to use local variables like 'thisModule' in scope of the given 'functionToRun' without passing them as parameters.

Onsetsu.run = function (functionToRun) {
    var thisModule = Onsetsu.namespace(resolvedModule.moduleName);
    functionToRun();
};

Onsetsu.run(function() {
    /* thisModule should be visible here */
});

Unfortunately 'thisModule' is not defined in the scope. Is there a convinient way to bring 'thisModule' into the functions scope?

Stefan Ramson
  • 531
  • 1
  • 6
  • 18
  • The convenient way is to pass it as an argument. – lqc Nov 19 '12 at 19:20
  • Well, as said, passing them as parameters would not fulfill the requirements. Passing them as parameters would freeze the order the parameters are taken, which leads to a less modular and less maintainable way to access the given variables. – Stefan Ramson Nov 19 '12 at 19:30
  • @Stefan - I'm confused. The function isn't passed any parameters at all, so there is no order of parameters. – gilly3 Nov 19 '12 at 19:46
  • Which parameters are you talking about? – Felix Kling Nov 19 '12 at 20:06
  • I was just decribing why I do not want to use parameters, so it's a "what if"-scenario. – Stefan Ramson Nov 19 '12 at 21:10
  • Well, if you just pass one object and consider its properties as arguments (just like a lot of libraries do it, like jQuery's `.ajax`), then you don't have to worry about order. – Felix Kling Nov 20 '12 at 00:03

2 Answers2

1

You can attach thisModule to the this reference inside functionToRun

Onsetsu.run = function (functionToRun) {
    var thisModule = Onsetsu.namespace(resolvedModule.moduleName);
    functionToRun.apply(thisModule,[]);
};

So inside your function you can refer to thisModule like so:

function myFunc(){
    console.log(this); // which will refer to thisModule
}
Onsetsu.run(myFunc);
Ibu
  • 42,752
  • 13
  • 76
  • 103
  • The con is that you can only have one this. If you need other modules, you'll have to wrap them in an object. – thunderflower Nov 19 '12 at 19:15
  • @thunderflower that is correct, but it is also a good start, you can always use the second parameter of the apply method to pass other stuff – Ibu Nov 19 '12 at 19:19
  • I already considered this as an option, but was not satisfied to use the this reference, because I wanted to apply the function later to different contexts while preserving the locals. – Stefan Ramson Nov 19 '12 at 19:22
  • @StefanLehmann you are currently calling the function as an anonymous function, so this is refering to the window object. – Ibu Nov 19 '12 at 19:27
1

Define a variable in the closest shared scope of functionToRun and Onsetsu.run. Assign the variable within Onsetsu.run:

var thisModule;
Onsetsu.run = function (functionToRun) {
    thisModule = Onsetsu.namespace(resolvedModule.moduleName);
    functionToRun();
};

Onsetsu.run(function() {
    /* thisModule should be visible here */
});

Assuming your actual code is more complicated than that:

(function(){
    var thisModule;
    var Onsetsu = (function(){
        var resolvedModule = { moduleName: "something" };
        return {
            run: function (functionToRun) {
                thisModule = Onsetsu.namespace(resolvedModule.moduleName);
                functionToRun();
            },
            namespace: function(moduleName){ ... }
        };
    })();
    Onsetsu.run(function() {
        /* thisModule should be visible here */
    });
})();

If Onsetsu is a library that you can't (or don't want to) modify, then you are out of luck.

Edit: You could also assign a property on the function itself:

Onsetsu.run = function (functionToRun) {
    var thisModule = Onsetsu.namespace(resolvedModule.moduleName);
    functionToRun.module = thisModule;
    functionToRun();
};

You can access the property from within functionToRun via arguments.callee:

Onsetsu.run(function() {
    var module = arguments.callee.module;
});

Or by giving the function a name:

Onsetsu.run(function fn() {
    var module = fn.module;
});
gilly3
  • 87,962
  • 25
  • 144
  • 176
  • Unfortunately the to code fragments are even in separate files(a core library and asynchronous loaded modules, which are executed using the `Onsetsu.run` function). – Stefan Ramson Nov 19 '12 at 19:39
  • @Stefan - Then the closest shared scope would be the global scope. If you want to avoid namespace polution, expose it as a property of `Onsetsu`. Or, use the other option I added to my answer just now. – gilly3 Nov 19 '12 at 19:42