2016-08-04 24 views
8

ES6 ab wir haben const.Bedingte Initialisierung einer Konstante in Javascript

Dies ist nicht erlaubt:

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

Dies macht Sinn, weil es uns von der Nutzung der Konstante verhindert, bevor es initialisiert wird.

Aber wenn ich

if(condition) 
    const x = 5; 

else 
    const x = 10; 

x wird Block scoped.

Also, wie man eine Konstante bedingt erstellt?

Antwort

11

Ihr Problem, wie Sie wissen, ist, dass ein const in der werden muss intialised dieselbe Anweisung, in der es deklariert wurde.

Dies bedeutet nicht, dass der Wert, den Sie Ihrer Konstante zuweisen, ein Literalwert sein muss. Es könnte jede gültige Aussage wirklich - ternär sein:

const x = IsSomeValueTrue() ? 1 : 2; 

Oder vielleicht einfach zuweisen Sie den Wert einer Variablen?

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

const x = y; 

Sie könnten natürlich weisen es der Rückgabewert einer Funktion, auch:

function getConstantValue() { 
    return 3; 
} 

const x = getConstantValue(); 

Es gibt also viele Möglichkeiten, den Wert dynamisch zu machen, müssen Sie nur sicher, dass nur zugewiesen es machen in einem Platz.

+0

Funktionsweise ist sauberer, wenn wir lange Bedingungen und Berechnungen haben (wie in meinem Fall), die mit ternärem Operator chaotisch aussehen würden. –

+0

Ich stimme zu, dass die Funktionsmethode wahrscheinlich die sauberste ist, besonders für kompliziertere Bedingungen. Wählen Sie einfach die Methode aus, die am besten zu Ihrem Anwendungsfall passt :) – Hecksa

+0

Ich bevorzuge die letzte Option (Funktion), da Sie die Logik ändern, wiederverwenden oder sogar Unit testen können, ohne vom Rest der Klasse abhängig zu sein. – ssube

3

Unter der Annahme, dass die const in beiden Instanzen erklärt werden wird, können Sie eine ternäre Zuordnung verwenden:

const x = condition ? 5 : 10; 
+0

Ich denke, sie werden gelehrt, dass ternäre '?' Ist ein Übel, nicht lesbarer Stil. Es besiegt "sich wiederholen" -Prinzip, das so genannte "Lesbarkeit" basiert auf :) –

+0

Wenn ich mehrere Konstanten deklariere, müsste ich die Bedingung für jeden von ihnen wiederholen. 'x = cond? a: b; y = cond? e: f' –

+2

@ArjunU. Lese 'const [a, b] = [x, y] 'Zuweisung. –

4

Wenn ternärer Operator ist keine Option für die Unlesbarkeit, die einzige andere Möglichkeit ist IIFE, das kann mühsam ist, aber flüssig zu lesen:

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

Die Semantik const ist, dass es einmal vergeben wird. Es sollte let für diesen Anwendungsfall sein:

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

Aus meiner persönlichen Erfahrung, ~ 95% der Variablen sind const. Wenn eine Variable let sein muss, lass es einfach selbst sein; Die Wahrscheinlichkeit von Fehlern, die durch zufällige Neuzuweisungen verursacht werden, ist vernachlässigbar.

+0

IIFE scheint die beste Lösung für den in den Kommentaren von OP – CodingIntrigue

+1

definierten Anwendungsfall zu sein. Wenn ein Ternär nicht lesbar ist, wie auf der Erde ist ein IIFE * besser *? Das ist deutlich weniger lesbar. – ssube

+0

@ssube IIFEs sind etablierte Sprachkonstruktionen, die von fließenden JS Lautsprechern automatisch interpretiert werden können, Pfeile machen sie schlanker, richtige Einrückungen und Klammern helfen auch. Das ist subjektiv, aber es sollte beachtet werden, dass es in der Antwort kein Wort "besser" gibt, und das Wort "Erde" macht das Argument nicht gültiger. Die Tatsache, dass IIFEs nicht für dich arbeiten, bedeutet nicht, dass sie nicht für alle funktionieren, danke für den kommentierten Downvote. – estus

0

Ich schlage vor, diese Lösung mit einer Singleton Pattern Umsetzung:

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