2011-03-24 28 views
2

我正在撕掉我的头发以完成此操作...特别是对于html5检测脚本。我想要一个只能设置一次而又不能被覆盖的变量。这是它:Javascript中的静态变量只能设置一次

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不再为空。所以我实际上使用下划线来“隐藏”静态变量。

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

+0

在什么情况下会是变量会被覆盖?我想检测脚本无论如何只运行一次? – 2011-03-24 18:39:32

+0

好吧,没有检查,你可以很容易地做 StaticConfiguration.setVariable(“html5”,“bla”); StaticConfiguration.setVariable(“html5”,“boom”); StaticConfiguration.setVariable(“html5”,“bang”); ...和变量总是会被设置 - 这就是我想要避免的。 – 2011-03-26 11:37:51

回答

5

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

其次,你是否真的需要保护这样的数据?无论如何,没有任何方法可以安全地运行用户的Javascript。总是有这样的保护方法。如果有问题的代码真的关心,它可能只是取代整个StaticConfiguration对象。

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

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

个人旁注:我恨与激情格式化“关于自己的行花括号”!

+0

-1。既然你没有创建一个新的对象,这是'window'。 – 2011-03-24 19:08:52

+0

谢谢你指出。固定。 – nitro2k01 2011-03-24 19:21:00

+0

这真的很棒。非常感谢。我也喜欢把东西放在Singletons(命名空间)中,所以这对我来说是一个完美的解决方案。 – 2011-03-26 11:56:19

1

看看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) { 
     ... 
    } 
    }; 
)(); 
1

如何:

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

其他答案相似,但仍允许任意键。这是真正的私人,不像下划线解决方案。

1

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

作为一个方面说明,当涉及到客户端脚本时,我在KISS原理,尤其是上相当大。

+0

正如我写的那样,对我来说这个变量是设置一次或永远不变的。确实,浏览器检测应该只发生一次。对于其他的东西(GET变量),它可能会不同。也可能发生另一个类(来自另一个开发者的概率)跳入并尝试再次设置相同的变量 - 你是对的,这不应该发生,但我的意图是让它变得“安全”。 – 2011-03-26 11:49:56

0

我知道我有点迟到了,但在这样的情况下,我通常

var data; 

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