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?

6
  • The convenient way is to pass it as an argument. Commented Nov 19, 2012 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. Commented Nov 19, 2012 at 19:30
  • @Stefan - I'm confused. The function isn't passed any parameters at all, so there is no order of parameters. Commented Nov 19, 2012 at 19:46
  • Which parameters are you talking about? Commented Nov 19, 2012 at 20:06
  • I was just decribing why I do not want to use parameters, so it's a "what if"-scenario. Commented Nov 19, 2012 at 21:10

2 Answers 2

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;
});
Sign up to request clarification or add additional context in comments.

2 Comments

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 - 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.
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);

4 Comments

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 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
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.
@StefanLehmann you are currently calling the function as an anonymous function, so this is refering to the window object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.