将功能放在另一个范围内?

时间:2015-09-03 09:07:51

标签: javascript scope instance-variables

我有一个(非常)简化的类看起来像这样:

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

现在,当我传递选项配置对象时(可能包含理论上无限数量的函数,而这些函数反过来引用类对于该类的每个实例都不同的类)... < / p>

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

var instance = new myClass(config);

...当然这些变量在函数范围内是不可访问的。如何将配置中的函数放入类范围?

bind出现在我的脑海中,但它只会更改this上下文,而不是范围。我可以将变量作为参数传递给函数,但是然后每个函数都必须检查内部的参数,并且关于来自外部配置对象的函数数量可能超出我的控制范围,我想防止这是一个先决条件。

有没有办法克隆&#34;函数进入类范围或类似的东西?闭包可以以任何方式提供帮助(如果是这样,请举例说明,因为我还没有把我的思想完全包裹在闭包中)。

谢谢!

2 个答案:

答案 0 :(得分:2)

这是我的版本

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

var instance = myClass({
  "action": function(instanceVar) {
    console.log(instanceVar); 
  }
});

js fiddle:https://jsfiddle.net/e0pgs4vw/

答案 1 :(得分:1)

instanceVar在闭包内定义,因此除非明确传递,否则无法从外部访问它。

为了防止需要将它传递给每个方法,您可以从configObject创建一个新的configInstance,并将instanceVar作为属性添加到新实例中:

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