闭包中的Javascript实例化。如何使工厂和模型独立?

时间:2015-09-27 00:11:41

标签: javascript closures

这是一个浏览器。 Js-code示例非常简单。

案例1:

var settingsImportantPrefix = {
     primitiveProperty: 1
};

var Model = function() {
     var self = this;
     self.getA = function() {
          return settings.primitiveProperty;
     }
};

var factory = function(settings) {
     return (function(settings) {
          return new Model();
     }(settings));
}

var test = factory(settingsImportantPrefix );
test.getA();

它对我不起作用。此示例中的闭包设置在返回的模型的新实例中不可见!

但另一方面。

案例2:

var settingsImportantPrefix = {
  primitiveProperty: 1
};

var factory = function(settings) {
  return (function(settings) {
    var Model = function() {
      var self = this;
      self.getA = function() {
        return settings.primitiveProperty;
      }
    };
    return new Model();
  }(settings));
};

var test = factory(settingsImportantPrefix);
test.getA() //1

按照它的要求工作。设置在新实例中可见。

在我看来有点奇怪的是,闭包不会创建自己的存储值范围。将模型函数体保持在闭包体内是否为“闭包定义”要求?

有没有办法让模特和工厂独立?

我的目标是将工厂和模型分开。我将设置对象(包装到Model中)作为参数传递,因此我需要检查它是否是Model的一个实例(这就是Model必须独立的原因)。

P.S。:我不喜欢以下列方式返回Model的想法:Factory.Model。

2 个答案:

答案 0 :(得分:3)

它有所不同,因为有不同的范围。当你调用一个函数时,它不会继承调用它的代码的范围,它会在创建它时获得它的范围。

这可以更简单;这不起作用,因为变量a不在创建函数show的范围内:

function show() {
  console.log(a);
}

function caller() {
  var a = 1;
  show();
}

这是有效的,因为变量a位于创建函数show的范围内:

function caller() {
  var a;

  function show() {
    consle.log(a);
  }

  a = 1;
  show();
}

这也有效,因为变量a在创建函数show的范围内,并且它不需要在调用函数的范围内:

function creator() {
  var a = 1;

  function show() {
    console.log(a);
  }

  return show;
}

var showFunc = creator();
showFunc();

答案 1 :(得分:3)

首先 - 你的例子的输出在第一种情况下是错误的 - 第一种情况是在你写的时候生成this.context = context 而不是1

但是,虽然它们具有相同的输出但两者之间存在差异。 函数内部使用的变量范围是在定义函数时确定的,而不是在使用时确定的。

在您的第一种情况下 - 正在使用的设置对象是全局 undefined变量,而在第二种情况下 - 使用的settings变量是本地变量。但是,因为JavaScript中的对象通过引用传递 - 它最终使用相同的变量(更改settings的值将在两种情况下更改输出。