【问题标题】:Static variable in Javascript that is set only onceJavascript中的静态变量,只设置一次
【发布时间】:2011-03-24 18:33:07
【问题描述】:

为了完成这项工作,我煞费苦心……尤其是对于 html5 检测脚本。我想要一个只设置一次并且不能再次覆盖的变量。就是这样:

var StaticConfiguration = {};
StaticConfiguration.Main = {
    _html5: null
}
StaticConfiguration.getVariable = function(name) {
    return StaticConfiguration.Main["_" + name];
}
StaticConfiguration.setVariable = function(name, value) {
    if(StaticConfiguration.Main["_" + name] == null) {
        StaticConfiguration.Main["_" + name] = value;
    }
}

首先,我定义了一个包含所有这些变量的全局对象 StaticConfiguration - 在我的例子中,只是“html5”。我将其设置为 null,因为我想在应用程序中设置它。为此,我打电话给

StaticConfiguration.setVariable("html5", "true");

然后就设置好了。如果我尝试再次设置它,它会失败 - 当然,因为 _html5 不再为空。所以我实际上使用下划线来“隐藏”静态变量。

这对我帮助很大。我希望这是一个好方法 - 如果不是,请告诉我:)

【问题讨论】:

  • 在什么情况下该变量会被覆盖?我想检测脚本无论如何只运行一次?
  • 好吧,没有检查你可以很容易地做 StaticConfiguration.setVariable("html5", "bla"); StaticConfiguration.setVariable("html5", "boom"); StaticConfiguration.setVariable("html5", "bang"); ...并且变量将始终被设置 - 这就是我想要避免的。

标签: javascript oop variables setter getter


【解决方案1】:

首先,它是true,而不是"true" 所有字符串(除了空字符串)评估为真,包括字符串"false"

其次,您真的需要像这样保护数据吗?无论如何,实际上没有任何方法可以在您的上下文中安全地运行用户的 Javascript。总有办法绕过这样的保护。如果违规代码真的很在意,它可以替换整个 StaticConfiguration 对象。

Matthew 的代码是解决问题的更好方法,但它不遵循单例模式,而是需要实例化的类。如果你想要一个带有“静态”变量的对象,我会这样做。

StaticConfiguration = new (function()
{
  var data = {}
  this.setVariable = function(key, value)
  {
    if(typeof data[key] == 'undefined')
    {
      data[key] = value;
    }
    else
    {
      // Maybe a little error handling too...
      throw new Error("Can't set static variable that's already defined!");
    }
  };

  this.getVariable = function(key)
  {
    if (typeof data[key] == 'undefined')
    {
      // Maybe a little error handling too...
      throw new Error("Can't get static variable that isn't defined!");
    }
    else
    {
      return data[key];
    }
  };
})();

个人旁注:我讨厌热情洋溢的“大括号在自己的行上”格式!

【讨论】:

  • -1。由于您没有创建新对象,因此这是 window
  • 这真的很棒。非常感谢。我也更喜欢把东西放在 Singletons(命名空间)中,所以这对我来说是一个完美的解决方案。
  • 我喜欢它的外观,它比我今天早些时候尝试实现的更好(但相似)。告诉我,由于变量是一个新的闭包,它每次调用时是否正确更新和存储新变量?我会这样打电话给StaticConfiguration.setVariable(key, value)吗? (这里有点菜鸟)
【解决方案2】:

查看 Crockford 在Private Members in JavaScript 上的文章。你可以这样做:

var StaticConfiguration = (function() {
  var html5; /* this is private, i.e. not visible outside this anonymous function */

  return {
    getVariable: function(name) {
      ...
    },

    setVariable: function(name, value) {
      ...
    }
  };
)();

【讨论】:

    【解决方案3】:

    怎么样:

    var StaticConfiguration = new (function()
    {
      var data = {}
      this.setVariable = function(key, value)
      {
        if(typeof data[key] == 'undefined')
        {
          data[key] = value;
        }
      };
    
      this.getVariable = function(key)
      {
        return data[key];
      };
    })();
    

    类似于另一个答案,但仍然允许任意键。与下划线解决方案不同,这确实是私有的。

    【讨论】:

      【解决方案4】:

      我有点好奇为什么您认为必须达到这种程度才能保护数据不被覆盖。如果您正在检测浏览器,不应该只检测一次吗?如果有人用无效数据覆盖它,那么我认为这将是客户端实现中的问题,而不是库代码 - 这有意义吗?

      顺便说一句,我非常重视 KISS 原则,尤其是在客户端脚本方面。

      【讨论】:

      • 正如我所写的那样,变量设置一次或从不设置对我来说很重要。确实,浏览器检测应该只发生一次。对于其他事物(GET 变量),它可能会有所不同。也可能发生另一个类(可能来自另一个开发人员)跳进来并尝试再次设置相同的变量 - 你是对的,这不应该发生,但我的意图是让它变得“安全”。跨度>
      【解决方案5】:

      我知道我参加聚会有点晚了,但在这种情况下我通常

      var data;
      
      if (data === undefined || //or some other value you expect it to start with{
      data = "new static value"
      };
      

      【讨论】:

        猜你喜欢
        • 2020-12-09
        • 2018-01-04
        • 2021-10-23
        • 1970-01-01
        • 2020-06-22
        • 1970-01-01
        • 2010-12-04
        • 1970-01-01
        相关资源
        最近更新 更多