Javascript 在闭包中实例化。如何让 Factory 和 Model 独立?

Javascript instantiation in a closure. How to make Factory and Model independent?

这是一个浏览器。js代码示例非常简单。

案例一:

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

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

但另一方面。

案例二:

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

按预期工作。设置在新实例中可见。

在我看来,闭包不创建自己的范围来存储值有点奇怪。 "closure definition" 要求将模型函数体保留在闭包体内吗?

有没有办法让Model和Factory独立?

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

P.S.: 我不喜欢 return 以下列方式建模的想法 Factory.Model.

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

这可以更简单地显示;这不会起作用,因为变量 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 而不是你写的 undefined

但是,尽管它们具有相同的输出,但两者之间还是有区别的。 当您 定义 函数时而不是当您 使用 函数时确定函数内部使用的变量范围。

在第一种情况下 - 正在使用的设置对象是 global settings 变量,而在第二种情况下 - settings 变量使用的是 local 变量。但是,由于 JavaScript 中的对象通过引用传递 - 它最终使用相同的变量(更改 settings.primitiveProperty 的值将改变两种情况下的输出。