398 Stimmen

Warum sollte man in JavaScript Inkrement- ("++") und Dekrement-Operatoren ("--") vermeiden?

Einer der Tipps für jslint Werkzeug ist:

++ y --
Die ++ (Inkrement) und -- (Dekrement) Operatoren sind dafür bekannt, dass sie zu schlechtem Code beitragen, indem sie zu übermäßiger Trickserei ermutigen. Sie sind nach einer fehlerhaften Architektur der zweitwichtigste Faktor zu Viren und anderen Sicherheitsbedrohungen Sicherheitsbedrohungen. Es gibt eine Plusplus Option, die die Verwendung dieser Operatoren verbietet.

Ich weiß, dass PHP-Konstrukte wie $foo[$bar++] kann leicht zu Fehlern führen, aber ich konnte keinen besseren Weg finden, die Schleife zu kontrollieren als a:

while( a < 10 ) do { /* foo */ a++; }

ou

for (var i=0; i<10; i++) { /* foo */ }

Ist die jslint hervorzuheben, da es einige ähnliche Sprachen gibt, denen das " ++ " und " -- "Syntax zu verwenden oder anders zu handhaben, oder gibt es andere Gründe für die Vermeidung von " ++ " und " -- ", die ich vielleicht übersehen habe?

19voto

Paul Sonier Punkte 37609

Die "pre"- und "post"-Natur der Inkrement- und Dekrement-Operatoren kann für diejenigen, die nicht mit ihnen vertraut sind, verwirrend sein; das ist eine Art, wie sie schwierig sein können.

18voto

Eric Punkte 18971

Betrachten Sie den folgenden Code

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[i++] = i++;
    a[i++] = i++;
    a[i++] = i++;

Da i++ zweimal ausgewertet wird, lautet die Ausgabe (vom vs2005-Debugger)

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Betrachten Sie nun den folgenden Code:

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = ++i;
    a[++i] = ++i;
    a[++i] = ++i;

Beachten Sie, dass die Ausgabe dieselbe ist. Sie könnten nun denken, dass ++i und i++ dasselbe sind. Das sind sie aber nicht

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Zum Schluss noch der folgende Code

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = i++;
    a[++i] = i++;
    a[++i] = i++;

Die Ausgabe lautet nun :

    [0] 0   int
    [1] 1   int
    [2] 0   int
    [3] 3   int
    [4] 0   int
    [5] 5   int

Sie sind also nicht dasselbe, aber beide führen zu einem nicht so intuitiven Verhalten. Ich denke, dass for-Schleifen mit ++ in Ordnung sind, aber passen Sie auf, wenn Sie mehrere ++-Symbole in der gleichen Zeile oder der gleichen Anweisung haben

18voto

Sri Punkte 4217

Meiner Meinung nach, "Explizit ist immer besser als implizit". Denn irgendwann kann es passieren, dass Sie mit dieser Inkrementen-Anweisung durcheinander kommen y+ = x++ + ++y . Ein guter Programmierer macht seinen Code immer besser lesbar.

15voto

Stuart Wakefield Punkte 6124

Ich habe mir das Video von Douglas Crockford zu diesem Thema angeschaut und seine Erklärung für die Nichtverwendung von Inkrement und Dekrement ist, dass

  1. Es wurde in der Vergangenheit in anderen Sprachen verwendet, um die Grenzen von Arrays zu durchbrechen und alle Arten von Schlechtigkeit und
  2. Dass sie eher verwirrend ist und unerfahrene JS-Entwickler nicht genau wissen, was sie tut.

Erstens sind Arrays in JavaScript dynamisch dimensioniert, und daher ist es, verzeihen Sie mir, wenn ich falsch liege, nicht möglich, die Grenzen eines Arrays zu überschreiten und auf Daten zuzugreifen, auf die mit dieser Methode in JavaScript nicht zugegriffen werden sollte.

Zweitens, sollten wir Dinge vermeiden, die kompliziert sind? Das Problem ist doch nicht, dass wir diese Möglichkeit haben, sondern dass es Entwickler gibt, die behaupten, JavaScript zu beherrschen, aber nicht wissen, wie diese Operatoren funktionieren? Es ist ganz einfach: value++ gibt mir den aktuellen Wert und fügt nach dem Ausdruck noch einen hinzu, ++value erhöht den Wert, bevor er mir gegeben wird.

Ausdrücke wie a ++ + ++ b sind einfach zu berechnen, wenn man sich die obigen Angaben merkt.

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

Ich nehme an, Sie müssen nur daran denken, wer den Code durchlesen muss. Wenn Sie ein Team haben, das JS in- und auswendig kennt, brauchen Sie sich keine Sorgen zu machen. Wenn nicht, dann kommentieren Sie ihn aus, schreiben Sie ihn anders, usw. Tun Sie, was Sie tun müssen. Ich glaube nicht, dass Inkrement und Dekrement von Natur aus schlecht sind oder Fehler erzeugen oder Schwachstellen schaffen, vielleicht nur weniger lesbar, je nach Zielgruppe.

Im Übrigen halte ich Douglas Crockford ohnehin für eine Legende, aber ich denke, er hat wegen eines Betreibers, der das nicht verdient hat, viel Aufsehen erregt.

Ich lebe dafür, das Gegenteil zu beweisen...

14voto

Hans Malherbe Punkte 2908

Der wichtigste Grund für die Vermeidung von ++ oder -- ist, dass die Operatoren Werte zurückgeben und gleichzeitig Seiteneffekte verursachen, was es schwieriger macht, über den Code nachzudenken.

Um der Effizienz willen ziehe ich das vor:

  • ++i wenn nicht verwendend der Rückgabewert (kein temporärer Wert)
  • i++ wenn mit den Rückgabewert (kein Pipeline-Stillstand)

Ich bin ein Fan von Mr. Crockford, aber in diesem Fall muss ich ihm widersprechen. ++i ist 25% weniger Text zu parsen als i+=1 y wohl deutlicher.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X