views:

105

answers:

3

I am working on a javascript framework. I have several independent scripts that look like this:

core.modules.example_module = function(sandbox){
    console.log('wot from constructor ==', wot);

  return{
    init : function(){
      console.log('wot from init ==', wot);
    }
  };
};

this function is called from another external script. I am trying to pass variables in to this function so that they can be accessed without using the this keyword.

The above example will error out saying wot is undefined.

If i wrap the function in an anonymous function and declare the variables there I get the expected desired results

(function(){

var wot = 'omg';

core.modules.example_module = function(sandbox){
    console.log('wot from creator ==', wot);

  return{
    init : function(){
      console.log('wot from init ==', wot);
    }
  };
};

})();

What i am trying to do is declare the variables further up the scope chain so they can be accessed in the module without using the this keyword like the second example. I don't believe this is possible as it looks like the functions execution scope is sealed on declaration of the function.

update
To clarify where I am trying to define wot. In a separate javascript file I have an object that calls a register module function like this

core = function(){
   var module_data = Array();
   return{
    registerModule(){
      var wot = "this is the wot value";
      module_data['example_module'] = core.modules.example_module();
    }
  };
};
A: 

Putting var wot; at the beginning of your constructor ought to do it

core.modules.example_module = function(sandbox){
  var wot;
  wot = 'foo'; //just so you can see it working
  console.log('wot from constructor ==', wot);

  return{
    init : function(){
      console.log('wot from init ==', wot);
    }
  };
};
Tobias Cohen
+2  A: 

Consider this example, using your code

var core = {}; // define an object literal
core.modules = {}; // define modules property as an object

var wot= 'Muhahaha!';

core.modules.example_module = function(sandbox){

  console.log('wot from creator ==', wot);

  return {
    init: function() {
       console.log('wot from init ==', wot);

    }
  }
}

// logs wot from creator == Muhahaha! to the console    
var anObject = core.modules.example_module(); 

// logs wot from init == Muhahaha! to the console
anObject.init(); 

So long as wot is defined somewhere in the scope chain for core.modules.example_module at the point at which it is executed, this will work as expected.

Slightly off topic, but you've touched upon the scope of functions. Functions have lexical scope, that is they create their scope at the point at which they are defined (as opposed to executed) and allows for closures to be created; A closure is created when a function has keeps a link to it's parent scope even after the parent has returned.

Russ Cam
+2  A: 

What you're looking for is called "dynamic scoping", where bindings are resolved by searching the current call-chain. It's not too common outside of the Lisp family (Perl supports it, via the local keyword). Dynamic scoping is not supported in JS, which uses lexical scoping.

outis