2011-03-24 75 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" 
};