Search code examples
javascriptscopeinstance-variables

Put function in another scope?


I have a class that (very) simplified looks like this:

var myClass = (function( window ) {
  function myClass(configObject) {
    var instanceVar = 'something that is different for every instance of myClass';
    configObject.action && configObject.action();
  }
  return myClass;
})(window);

Now when I pass the option config object (which may contain a theoretically unlimited number of functions that in turn reference variables from the class that are different for every instance of that class) ...

var config = {
  "action": function() {
    concole.log(instanceVar); // is undefined when called from myClass, because it's in another scope
  }
};

var instance = new myClass(config);

... of course those vars are not accessible in the function scope. How can I put the functions from the config into the class scope?

bindcame to my mind, but it only changes the thiscontext, not the scope. I could pass the variable as argument to the function, but then every function would have to check for that argument inside, and with regard to the number of functions coming from the external configuration object that may be out of my control, I would like to prevent making this a prequisite.

Is there a way to "clone" the functions into class scope or anything like that? Could closures be helpful in any way (and if so, please exemplify, as I haven't wrapped my mind around closures completely yet).

Thanks!


Solution

  • instanceVar is defined inside a closure, so you can't access it from outside unless explicitly passed.

    To prevent the need for passing it to each method, you can create a new configInstance from configObject, and add instanceVar as property to the new instance:

    var myClass = (function(window) {
      function myClass(configObject) {
        var instanceVar = 'something that is different for every instance of myClass';
    
        var configInstance = Object.create(configObject, { // create a new configInstance that inherits from the origin configObject, which means that the original won't be changed
          instanceVar: {
            writable: false,
            configurable: false,
            value: instanceVar
          } // add instanceVar as a member to configInstance 
        });
    
        configInstance.action && configInstance.action();
      }
      return myClass;
    })(window);
    
    var config = {
      "action": function() {
        console.log(this.instanceVar);
      }
    };
    
    var instance = new myClass(config);