2015-04-04 5 views
5

Kennt jemand einige Tricks, wie man es macht? Ich habe versucht, try-catch zu verwenden:Wie überprüft man, dass ES6 "Variable" konstant ist?

"use strict"; 

const a = 20; 

var isConst = false; 
try { 
    var temp = a; a = a+1; a = temp; 
} catch (e) { 
    isConst = true; 
} 

Aber leider funktioniert es nur in „streng“ -Modus. Ohne "use strict" führt sie alle Anweisungen ohne Änderung von a automatisch aus. Auch kann ich diesen Code nicht in eine handliche Funktion (isConstant(someConst) zum Beispiel) einbinden, da jedes Argument, das ich an diese Funktion übergebe, eine neue Variable sein wird. Also kann jemand isConstant() Funktion erstellen?

+0

Für mich 'const a = 2; a ++;' wirft einen 'SyntaxError' (" ungültige Zuweisung zu const a ") mit Firefox 37.0, auch ohne strict mode und ich habe' javascript.options.strict' nicht aktiviert. Eine andere ist ein 'TypeError':" redeclaration of const a ", wenn ich" const a = 2; delete a; "oder" const a = 2; const a = 2; ". – Xufox

+0

Interessante Frage. Ich denke nicht, dass es für die meisten Browser möglich ist - zumindest [nach Mozillas Kompatibilitätsdiagramm] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const#Browser_compatibility)) - aber ich wäre sehr neugierig, ob es einen Weg gibt, es zu erkennen. – brianvaughn

+0

Welchen Browser benutzen Sie? Da es sich bei Firefox 37.0 um einen 'try-catch' handelt, der versucht, eine Konstante neu zu definieren und Syntaxfehler zu fangen, könnte das funktionieren. – Xufox

Antwort

1

Ich glaube nicht da ist, aber ich glaube nicht, dass dies auch ein großes Problem ist. Ich denke, es könnte nützlich sein, die Fähigkeit zu haben, zu wissen, ob eine Variable const ist, und das gibt es in einigen anderen Sprachen, aber in Wirklichkeit, da Sie (oder jemand in einem Team) diese Variablen definieren werden, würden Sie den Umfang kennen und der Typ der Variablen. Mit anderen Worten, nein, du kannst nicht, aber es ist auch kein Problem.

Der einzige Fall, in dem es nützlich sein könnte, wenn Sie die Eigenschaft mutable zur Laufzeit ändern könnten, und wenn das Ändern dieser Eigenschaft tatsächliche Leistungsvorteile hätte; etwa gleich den Compiler behandelt let, const und var sind, der einzige Unterschied ist, dass die Compiler Spur von const hält und Zuweisungen überprüfen, bevor es kompiliert sogar.

Eine andere Sache ist zu beachten, dass wie let, const auf den aktuellen Bereich scoped ist, also, wenn Sie etwas wie folgt aus:

'use strict'; 

const a = 12; 

// another scope 
{ 
    const a = 13; 
} 

es ist gültig. Genau darauf achtet, dass es in höheren Bereichen nachschlagen, wenn Sie nicht explizit const a = 13 in diesem neuen Bereich Staat tun, und es gibt einen Read Only oder Assignment Fehler: scheint

'use strict'; 

const a = 12; 

{ 
    a = 13; // will result in error 
} 
+0

Gute Antwort. Aber leider erzeugt v8 keinen Fehler, wenn Sie Ihr Skript im "nicht-strikten" Modus ausführen. - Danke. – alexpods

+0

Im Allgemeinen beschweren sich Linters wie 'jshint', wenn Sie' use strict; 'in Ihrem Code nicht haben, also halte ich das für einen strittigen Punkt. Es ist ziemlich selten, Code zu sehen, der 'use strict;' in jeder Art von Produktionseinstellung nicht enthält. – josh

+0

Nun, ich stimme dir zu. Upvote von mir. Aber eigentlich ist die Frage akademischer, kein wirkliches Problem. Ich bin nur gelegentlich zu dieser Frage gekommen, wie man richtig kontrolliert, dass "Variable" eine Konstante ist. Ich weiß nicht einmal den wirklichen Anwendungsfall, wo es nützlich sein kann. – alexpods

0

Es ist nicht möglich, richtig zu sein aus der Box. Derzeit ist es besser, sich an die transpilers für ES6-Entwicklung zu halten, und sie sind konsistent mit Wurffehlern, die spezifisch für ES6-Funktionen sind.

Es ist nützlich zu halten Konvention UPPERCASE_CONSTANT, die in anderen Sprachen verwendet wird, wurde angenommen speziell solche Fälle zu vermeiden.

0

überprüfen Sie einfach, ob Ihre Neuzuordnung tatsächlich etwas tat:

var isConst = function(name, context) { 
    // does this thing even exist in context? 
    context = context || this; 
    if(typeof context[name] === "undefined") return false; 
    // if it does exist, a reassignment should fail, either 
    // because of a throw, or because reassignment does nothing. 
    try { 
    var _a = context[name]; 
    context[name] = !context[name]; 
    if (context[name] === _a) return true; 
    // make sure to restore after testing! 
    context[name] = _a; 
    } catch(e) { return true; } 
    return false; 
}.bind(this); 

Sie den Versuch benötigen/da fängt neu zuweisen kann eine Ausnahme auslösen (wie in Firefox), aber wenn es nicht (wie in Chrome), überprüfen Sie einfach, ob Ihre Neuzuordnung „dies immer den Wert ändert“ tatsächlich tat nichts.

Ein einfacher Test:

const a = 4; 
var b = "lol"; 
isConst('a'); // -> true 
isConst('b'); // -> false 

Und wenn man die consts in anderen Kontext zu erklären, dass Zusammenhang passieren in der Auflösung auf das richtige Objekt zu erzwingen.

Nachteil: das funktioniert nicht auf Vars außerhalb des Objekts Tive erklärt. Upside: Es macht absolut keinen Sinn, sie irgendwo anders zu deklarieren.Zum Beispiel, sie in Funktionsumfang erklärt macht das const Stichwort meist nutzlos:

function add(a) { 
    return ++a; 
} 

function test() { 
    const a = 4; 
    console.log(add(a)); 
} 

test(); // -> 5 

Obwohl a konstanter Innen Test() ist, wenn Sie es noch etwas passieren, es als regulärer wandelbar Wert übergeben wird, weil es jetzt nur "eine Sache" in der arguments Liste.

Darüber hinaus ist der einzige Grund für eine const ist, weil es nicht ändert. Wenn Sie es also ständig neu erstellen, weil Sie eine Funktion aufrufen, die es mehr als einmal verwendet, bedeutet dies, dass Ihr const stattdessen außerhalb der Funktion leben sollte, also sind wir gezwungen, die Variable in einen Objektbereich zu stellen.

+0

Beachten Sie die 'context'-Variable, wo Sie in Ihrem eigenen Kontext übergeben können, wo Sie erwarten, dass die Variable lebt. –

+0

Nun, es funktioniert nicht, wenn Sie es im ersten Mal ausführen: '(function() {const e = 30; console.log (isConst ('e'));})()' Im zweiten Mal funktioniert es . – alexpods

+0

guten Punkt, lassen Sie mich sehen, ob ich die Antwort aktualisieren kann, um Sie dort zu decken. –