2016-08-04 12 views
8

ES6起,我們有const有條件地初始化Javascript中的常量

這是不允許的:

const x; //declare first 
//and then initialize it 
if(condition) x = 5; 
else x = 10; 

這是有道理的,因爲它妨礙我們從它的初始化之前使用常量。

但如果我這樣做

if(condition) 
    const x = 5; 

else 
    const x = 10; 

x變成塊作用域。

那麼如何有條件地創建一個常量?

回答

11

你的問題,如你所知,是一個const具有在被intialised同樣的聲明,它被宣佈。

這並不意味着你分配給你的常量的值必須是一個文字值。它可以是真正的任何有效聲明 - 三元組:

const x = IsSomeValueTrue() ? 1 : 2; 

或者,也許只是將它分配給一個變量的值?

let y = 1; 
if(IsSomeValueTrue()) { 
    y = 2; 
} 

const x = y; 

你當然可以把它分配給一個函數的返回值,太:

function getConstantValue() { 
    return 3; 
} 

const x = getConstantValue(); 

所以有很多的方式,使價值的動態,你只需要確保它只能分配在一個地方。

+0

如果我們有很長的條件和計算(在我的情況下),使用三元運算符會顯得雜亂,函數的方法更清潔。 –

+0

我同意函數方法可能是最乾淨的,特別是對於更復雜的條件。只需選擇最適合您的用例的方法:) – Hecksa

+0

我更喜歡最終選項(函數),因爲它可以讓您更改,重用甚至單元測試邏輯而不依賴於其他類。 – ssube

3

假設const會在實例聲明,你可以使用一個三元分配:

const x = condition ? 5 : 10; 
+0

我猜他們被教導三元':'是一個邪惡的,非可讀的風格。它擊敗'重複自己'的原則,即所謂的'可讀性'是基於:) –

+0

如果我聲明多個常量,我不得不重複每個人的條件。 'x = cond? a:b; y = cond? e:f' –

+2

@ArjunU。閱讀'const [a,b] = [x,y]'賦值。 –

4

如果三元運算符不是其不可讀性的選擇,唯一的選擇是IIFE,這是麻煩,但能流利地讀出:

const x = (() => { 
    if (condition) 
    return 5 
    else 
    return 10 
})(); 

const語義是,它被分配一次。它應該是let這個用例:

let x; 
if(condition) x = 5; 
else x = 10; 

從我個人的經驗,〜變量的95%const。如果一個變量必須是let,就讓它成爲它自己;由意外重新分配引起的錯誤的可能性可以忽略不計。

+0

如果一個三元不可讀,那麼IIFE *怎麼樣更好*?IIFE似乎是最好的解決方案,給出了OP – CodingIntrigue

+1

評論中定義的用例。這是可讀性顯着降低。 – ssube

+0

@ssube IIFE是建立的語言結構,可以通過流利的JS揚聲器自動解釋,箭頭使它們變得更苗條,正確的縮進和括號也有幫助。這是主觀的,但應該注意的是答案中沒有「更好」的詞,而「地球」這個詞不會使論證更有效。 IIFEs不適合你的事實並不意味着他們不適合每個人,無論如何感謝評論的downvote。 – estus

0

我建議這個解決方案可以與Singleton Pattern實現:

var Singleton = (function() { 
    var instance; 

    function createInstance() { 
     // all your logic here 
     // so based on your example: 
     // if(condition) return 5; 
     // else return 10; 
    } 

    return { 
     getInstance: function() { 
      if (!instance) { 
       instance = createInstance(); 
      } 
      return instance; 
     } 
    }; 
})(); 

const x = Singleton.getInstance();