Warum sollten Inkrement- ("++") und Dekrement- ("-") Operatoren in JavaScript vermieden werden?

357

Einer der Tipps für das jslint-Tool lautet:

++ und -
Es ist bekannt, dass die Operatoren ++ (Inkrementieren) und - (Dekrementieren) zu schlechtem Code beitragen, indem sie zu übermäßigen Tricks ermutigen. Sie sind nach fehlerhafter Architektur an zweiter Stelle, wenn es darum geht, Viren und andere Sicherheitsbedrohungen auszulösen. Es gibt eine Plusplus-Option, die die Verwendung dieser Operatoren verbietet.

Ich weiß, dass PHP-Konstrukte wie $foo[$bar++]has leicht zu Fehlern führen können, aber ich konnte keinen besseren Weg finden, um die Schleife zu steuern als ein while( a < 10 ) do { /* foo */ a++; }oderfor (var i=0; i<10; i++) { /* foo */ } .

Hebt der jslint sie hervor, weil es einige ähnliche Sprachen gibt, denen die Syntax " ++" und " --" fehlt oder die anders behandelt werden, oder gibt es andere Gründe, um " ++" und " --" zu vermeiden , die mir möglicherweise fehlen?

artlung
quelle
59
Man sollte also Array [index = index + 1] anstelle von Array [++ index] machen (wenn ersteres überhaupt erlaubt ist!). Was für eine Menge Scheiße.
Lawrence Dol
34
Ich habe Crockford nicht gesehen, wie er index = index + 1 macht. Ich habe gesehen, wie er Index + = 1 gemacht hat. Ich denke, das ist eine vernünftige Alternative. Und es ist schön, wenn Sie den Schritt auf etwas
anderes
124
Persönlich bin ich kein großer Fan von Crockford. Er scheint alles, was jemals einen Fehler in seinem Code verursacht hat, als böse anzusehen.
Paolo Bergantino
38
In JavaScript sollten Sie jeden Fehler als etwas böse betrachten, da es weder eine offizielle Dokumentation noch einen Zertifikatsanbieter gibt oder Sie JS an der Universität richtig lernen. Crockford und Firebug haben diese Lücken in der JavaScript-Ausbildung geschlossen.
Stevek
40
++verursacht keine Fehler. Die Verwendung ++auf "knifflige" Weise kann zu Fehlern führen, insbesondere wenn mehr als eine Person die Codebasis verwaltet. Dies ist jedoch kein Problem für den Bediener, sondern ein Problem für den Programmierer. Ich habe JS an der Universität nicht gelernt (weil es es noch nicht gab), aber was nun? Ich habe C gemacht, was natürlich ++zuerst war, aber das bekommt auch ein "na und?" Ich bin nicht zur Universität gegangen, um eine bestimmte Sprache zu lernen, sondern um gute Programmierpraktiken zu lernen, die ich auf jede Sprache anwenden kann .
nnnnnn

Antworten:

408

Meine Ansicht ist, immer ++ und - für sich in einer einzigen Zeile zu verwenden, wie in:

i++;
array[i] = foo;

anstatt

array[++i] = foo;

Alles darüber hinaus kann für einige Programmierer verwirrend sein und ist es meiner Ansicht nach einfach nicht wert. For-Schleifen sind eine Ausnahme, da die Verwendung des Inkrementoperators idiomatisch und somit immer klar ist.

cdmckay
quelle
3
Ja, das mache ich auch. Es ist schwer, etwas falsch zu machen, und es fällt anderen leichter, herauszufinden, was Sie tun.
Nosredna
65
Das scheint der Kern des Problems und meiner Verwirrung zu sein. Allein verwendet, i ++; ist kristallklar. Sobald Sie anderen Code um diesen grundlegenden Ausdruck hinzufügen, leiden Lesbarkeit und Klarheit.
Artlung
2
Stimmen Sie zu, aber es ist nicht nur JavaScript-bezogen
Tobias
5
Sie sagen nicht, ob Sie C oder C ++ schreiben. Möglicherweise sollten Sie den Präfix-Inkrement-Operator in C ++ verwenden, falls die iVariable später zu einer zusammengesetzten Klasse wird. In diesem Fall würden Sie unnötig ein temporäres Objekt erstellen. Ich finde den Postfix-Operator jedoch ästhetischer.
mc0e
2
Ich bevorzuge die 1-Zeilen-Version. Es erinnert an eine Stapeloperation. push ist array [++ i] = foo, pop ist bar = array [i--]. (Aber mit 0-basierten Arrays sehen Array [i ++] = foo und bar = Array [- i] noch besser aus). Eine andere Sache, ich würde es hassen, wenn jemand zusätzlichen Code zwischen i ++ hinzufügen würde; und Array [i] = foo;.
Florian F
257

Ich bin ehrlich gesagt verwirrt von diesem Rat. Ein Teil von mir fragt sich, ob es mehr mit mangelnder Erfahrung (wahrgenommen oder tatsächlich) mit Javascript-Codierern zu tun hat.

Ich kann sehen, wie jemand, der nur einen Beispielcode "abhackt", einen unschuldigen Fehler mit ++ und - machen kann, aber ich verstehe nicht, warum ein erfahrener Fachmann sie vermeiden würde.

Jon B.
quelle
7
Guter Punkt Jon B. Deshalb hat es mich so gestört. Crockford ist ein Karriere-Programmierer (im Wert von Jahrzehnten), der über Jahrzehnte mit mehreren Sprachen vertraut ist und seit seiner Gründung im Wesentlichen mit JavaScript arbeitet. Ich glaube nicht, dass sein Rat von "Ich bin fauler und unaufmerksamer unerfahrener Hacker" kommt - deshalb versuche ich zu verstehen, woher er kommt.
Artlung
14
@artlung Vielleicht hat es mehr mit "Ein fauler und unaufmerksamer unerfahrener Hacker" zu tun, der wahrscheinlich mit diesem Code herumspielt, und ich möchte ihn nicht verwirren.
Chris Cudmore
9
Ich bin mit Ihrer Antwort überhaupt nicht einverstanden. Meiner Meinung nach geht es nicht um "Bin ich genug Erfahrung, um es zu benutzen?" - aber "Ist klarer oder nicht?" Ob in einer for-Schleife oder alleine, es ist kristallklar - jeder wird das ohne Schaden verstehen. Das Problem tritt auf, wenn ein verschlungener ++Ausdruck in xx von x ++ verwendet wird, was zu etwas führt, das nicht leicht zu lesen ist. Bei der Crockford-Idee geht es nicht um "Kann ich das tun?" Es geht um "Wie kann ich Fehler vermeiden?"
ArtoAle
1
Es ist Ihre persönliche Präferenz, an welchem ​​Punkt Klarheit für Sie wichtiger ist als Kompaktheit. Dies geht über die Erfahrung hinaus, um den Code zu verstehen. In anderen Antworten finden Sie Beispiele, bei denen es mehr Probleme gibt als es wert ist.
Frug
1
Ich bin vollkommen einverstanden. Warum sollten Sie sich behindern, indem Sie keinen Teil der Sprache verwenden? Ich finde gute Gründe, sowohl Post- als auch Pre-Inkremente und Dekremente zu verwenden. Für mich ist eine solche Zeile klar und prägnant ... if (--imagesLoading === 0) start (); Wenn Sie der Meinung sind, dass Ihr Code unklar ist, verwenden Sie Kommentare!
xtempore
69

Es gibt eine Geschichte in C, Dinge zu tun wie:

while (*a++ = *b++);

Um eine Zeichenfolge zu kopieren, ist dies möglicherweise die Quelle der übermäßigen Tricks, auf die er sich bezieht.

Und es ist immer die Frage was

++i = i++;

oder

i = i++ + ++i;

tatsächlich tun. Es ist in einigen Sprachen definiert, und in anderen gibt es keine Garantie dafür, was passieren wird.

Abgesehen von diesen Beispielen gibt es meines Erachtens nichts Idiomatischeres als eine for-Schleife, die ++zum Inkrementieren verwendet wird. In einigen Fällen könnten Sie mit einer foreach-Schleife oder einer while-Schleife davonkommen, die einen anderen Zustand überprüft. Es ist jedoch lächerlich, Ihren Code zu verzerren, um die Verwendung von Inkrementierungen zu vermeiden.

Finsternis
quelle
104
i = i ++ + ++ i; machte meine Augen ein wenig weh - :)
Hugoware
3
Meine auch. Selbst wenn sie nicht alle dieselbe Variable wären, sagen wir, ich hätte x = a ++ + ++ b; - Diese Kombination macht es sofort schwieriger, x, a und b in meinem Kopf zu halten. Nun, wenn jede einzelne Anweisung in separaten Zeilen wäre, wie in - a ++; ++ b; x = a + b; es wäre auf den ersten Blick leichter zu verstehen.
Artlung
10
Leider ist (a ++; b ++; x = a = b) nicht der gleiche Wert wie (a ++ + ++ b).
Thomas L Holaday
8
@Marius: x = a+++b-> x = (a++)+b-> x = a + b; a++. Der Tokeniser ist gierig.
Callum Rogers
14
Entfernen Sie für zusätzliche Arbeitssicherheit die Leerzeichen in Ihrem letzten Beispiel.
mc0e
48

Wenn Sie JavaScript The Good Parts lesen, werden Sie sehen, dass Crockfords Ersatz für i ++ in einer for- Schleife i + = 1 ist (nicht i = i + 1). Das ist ziemlich sauber und lesbar und verwandelt sich weniger in etwas "Kniffliges".

Crockford hat das Deaktivieren von Autoincrement und Autodecrement in jsLint zu einer Option gemacht. Sie entscheiden, ob Sie dem Rat folgen möchten oder nicht.

Meine persönliche Regel ist, nichts in Verbindung mit Autoincrement oder Autodecrement zu tun.

Ich habe aus jahrelanger Erfahrung in C gelernt, dass ich keine Pufferüberschreitungen (oder Array-Indizes außerhalb der Grenzen) bekomme, wenn ich sie einfach verwende. Aber ich habe festgestellt, dass ich Pufferüberläufe bekomme, wenn ich in die "übermäßig knifflige" Praxis falle, andere Dinge in derselben Anweisung zu tun.

Für meine eigenen Regeln ist die Verwendung von i ++ als Inkrement in einer for- Schleife in Ordnung.

Nosredna
quelle
Hervorragender Punkt, dass die Option "plusplus" genau das ist, eine Option. Aufgrund Ihrer und anderer Antworten habe ich das Gefühl, dass ++ an sich oder eine for-Schleife an und für sich nicht verwirrend sind. Wenn Sie dieses ++ in einer anderen Anweisung kombinieren, wird es schwieriger, es im Kontext zu lesen und zu verstehen.
Artlung
6
Jeder bekommt Pufferüberläufe. Sogar OpenSSH mit ihrem Open Source und ihren zahlreichen Revisionskomitees
Eric
11
@ Eric Wiederholen Sie Ihren fünf Jahre alten Kommentar: Oh, wie richtig Sie waren!
wchargin
27

In einer Schleife ist es harmlos, aber in einer Zuweisungsanweisung kann es zu unerwarteten Ergebnissen führen:

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

Leerzeichen zwischen der Variablen und dem Operator können ebenfalls zu unerwarteten Ergebnissen führen:

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

Bei einem Abschluss können auch unerwartete Ergebnisse ein Problem sein:

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

Und es löst das automatische Einfügen von Semikolons nach einer neuen Zeile aus:

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

Verwirrung vor / nach dem Inkrementieren kann zu Fehlern führen, die äußerst schwer zu diagnostizieren sind. Zum Glück sind sie auch völlig unnötig. Es gibt bessere Möglichkeiten, einer Variablen 1 hinzuzufügen.

Verweise

Paul Sweatte
quelle
13
Aber sie sind nicht "unerwartet", wenn Sie den Operator verstehen. Es ist, als würde man nie etwas benutzen, ==weil man den Unterschied zwischen ==und nicht versteht ===.
Greg84
1
Genau. Es gibt eine C # -Frage, die falsche Annahmen entlarvt.
Paul Sweatte
Ich denke, Crockfords Argument ist, dass die meisten Programmierer den Operator nicht vollständig "verstehen", selbst wenn sie glauben, dies zu tun. Daher besteht die Gefahr, dass sie verwendet werden, da das Missverständnispotential hoch ist. Siehe @ Pauls Kommentar zu falschen Annahmen, der das Argument stützt, dass Menschen im Allgemeinen falsch verstehen, wie Präfix- und Postfix-Operatoren tatsächlich funktionieren. Trotzdem gebe ich zu, dass ich sie gerne benutze, aber für andere versuche ich, ihre Verwendung auf idiomatische Fälle zu beschränken (siehe die Antwort von cdmckay ).
Gfullam
Ihr Whitespace-Link scheint defekt zu sein.
Ruslan
Was ist schwierig an Ihrem "Whitespace" -Beispiel? Ich bekomme eine unkomplizierte Ausgabe von a: 2 b: 0 c: 1. Ich sehe auch im ersten Beispiel ("Zuweisungsanweisung") nichts Seltsames oder Unerwartetes.
Ken Williams
17

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, ist 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. Jetzt könnte man denken, dass ++ i und i ++ gleich sind. Sie sind nicht

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

Betrachten Sie abschließend diesen 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 ist jetzt:

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

Sie sind also nicht gleich. Das Mischen beider führt zu einem nicht so intuitiven Verhalten. Ich denke, dass for-Schleifen mit ++ in Ordnung sind, aber achten Sie darauf, wenn Sie mehrere ++ Symbole in derselben Zeile oder Anweisung haben

Eric
quelle
3
Vielen Dank für dieses Experiment. Besonders "einfach aussehender" Code, aber es wird für mein Gehirn schwierig, mich sehr schnell daran zu halten. Fällt definitiv in die Kategorie "knifflig".
Artlung
28
Ich hörte nach dem ersten Beispiel auf. Sie sagten "Betrachten Sie den folgenden Code". Nein, niemand schreibt diesen Code. Es ist der Idiot, der schreibt, wer fehlerhaft ist, kein Sprachkonstrukt.
Sam Harwell
4
Sie haben gezeigt, dass zwei verschiedene Codeteile unterschiedliche Ausgaben erzeugen, und dies beweist, dass es schlecht ist?
Nickf
7
Die Schlussfolgerung lautet "Achtung, wenn Sie mehrere ++ Symbole in derselben Zeile oder Anweisung haben". Ich glaube nicht, dass Sie es gelesen haben
Eric
1
"da i ++ zweimal ausgewertet wird" - falsch! Das zweimalige Ändern einer Variablen zwischen Sequenzpunkten und deren Verwendung ist in C ++ ungültig und führt zu undefiniertem Verhalten. Der Compiler kann also tun, was er will. Die hier dargestellten Ergebnisse stammen aus der Implementierung des Compilers.
Tbleher
16

Die "Vor" - und "Nach" -Natur von Inkrementierungs- und Dekrementierungsoperatoren kann für diejenigen, die mit ihnen nicht vertraut sind, verwirrend sein. Auf diese Weise können sie schwierig sein.

Paul Sonier
quelle
29
Einverstanden; Ein erfahrener Fachmann sollte jedoch nicht verwirrt werden.
Nate
1
Ich denke, dies ähnelt der Anleitung, um zu vermeiden, dass alles statisch oder global wird. Es ist an sich nichts Falsches daran als Programmierkonstrukt, aber ignorante Überbeanspruchung kann zu schlechtem Code führen.
Joel Martinez
6
Die Frage ist nicht, ob ein guter Programmierer sich durch die Logik "arbeiten" kann - guter Code erfordert im Idealfall keine Arbeit, um ihn zu verstehen. Ich denke, McWafflestix meint nur, dass Sie keinen Code schreiben sollten, der nach einer kurzen Überprüfung in zwei Wochen oder zwei Jahren zum Hinzufügen von Fehlern führen kann. Ich weiß, dass ich mich schuldig gemacht habe, einer Routine Code hinzugefügt zu haben, die ich nicht vollständig verstanden habe :)
Mike
1
@Mike: yah, beachte, dass ich nicht angegeben habe, ob die Operatoren für den ursprünglichen Autor des Codes oder für spätere Betreuer schwierig sein können. Im Allgemeinen versuchen wir anzunehmen, dass ursprüngliche Codierer keine Konstrukte verwenden, mit denen sie nicht vertraut sind (leider ist dies häufig eine falsche Annahme). Diese Vertrautheit erstreckt sich jedoch sicherlich nicht auf Betreuer (und, wie oben in Klammern angegeben, möglicherweise nicht einmal auf den ursprünglichen Autor).
Paul Sonier
Ich versuche, meinen Code für andere Programmierer zum Lesen zu schreiben , aber ich versuche nicht , ihn für Anfänger zum Lesen zu schreiben.
Luke H
16

Meiner Ansicht nach ist "Explizit immer besser als implizit". Denn irgendwann könnten Sie mit dieser Inkrement-Anweisung verwechselt werden y+ = x++ + ++y. Ein guter Programmierer macht seinen Code immer besser lesbar.

Sriram
quelle
1
In x ++ oder ++ y ist nichts impliziert.
Florian F
1
Diese Sache mit lesbarem Code ist schwierig ... Ich denke, es gibt eine Grundlinie dafür, wie einfach Ihr Code sein muss, und wir - als Community - müssen ein bisschen gedeihen und in der Lage sein, zu lesen, was jetzt nicht lesbar ist, wie z. B. Einzeiler mit verschachtelten Ternären, um mehr Dinge zu ermöglichen.
Hamza Ouaghad
14

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

Aus Gründen der Effizienz bevorzuge ich:

  • ++ i wenn der Rückgabewert nicht verwendet wird (kein temporärer Wert)
  • i ++ bei Verwendung des Rückgabewerts (kein Pipeline-Stall)

Ich bin ein Fan von Mr. Crockford, aber in diesem Fall muss ich nicht zustimmen. ++iist 25% weniger Text zu analysieren als i+=1 und wohl klarer.

Hans Malherbe
quelle
13

Ich habe Douglas Crockfords Video dazu gesehen und seine Erklärung dafür, dass er kein Inkrement und Dekrement verwendet, ist das

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

Erstens haben Arrays in JavaScript eine dynamische Größe. Wenn ich mich irre, ist es 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 komplizierte Dinge vermeiden, besteht das Problem sicherlich nicht darin, dass wir über diese Funktion verfügen, sondern darin, dass es Entwickler gibt, die behaupten, JavaScript zu verwenden, aber nicht wissen, wie diese Operatoren funktionieren? Es ist einfach genug. value ++, gib mir den aktuellen Wert und füge nach dem Ausdruck einen hinzu, ++ value, inkrementiere den Wert, bevor du ihn mir gibst.

Ausdrücke wie a ++ + ++ b sind einfach zu berechnen, wenn Sie sich nur an das Obige erinnern.

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 sich nur daran erinnern, 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 es, schreiben Sie es anders usw. Tun Sie, was Sie tun müssen. Ich denke nicht, dass Inkrementieren und Dekrementieren von Natur aus schlecht ist oder Fehler erzeugt oder Schwachstellen erzeugt, die je nach Zielgruppe möglicherweise nur weniger lesbar sind.

Übrigens denke ich, dass Douglas Crockford sowieso eine Legende ist, aber ich denke, dass er einem Betreiber, der es nicht verdient hat, viel Angst gemacht hat.

Ich lebe, um mich als falsch zu erweisen ...

Stuart Wakefield
quelle
10

Ein weiteres Beispiel, einfacher als einige andere mit einfacher Rückgabe eines inkrementierten Werts:

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

Wie Sie sehen, sollte bei der return-Anweisung kein Post-Inkrement / Dekrement verwendet werden, wenn dieser Operator das Ergebnis beeinflussen soll. Aber return "fängt" keine Operatoren nach dem Inkrementieren / Dekrementieren:

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}
Evgeny Levin
quelle
Nur eine Ihrer Funktionen erhält x als Parameter
Calimero100582
8

Ich denke, Programmierer sollten in der Sprache, die sie verwenden, kompetent sein. benutze es klar; und benutze es gut. Ich denke nicht, dass sie die Sprache, die sie verwenden, künstlich lähmen sollten. Ich spreche aus Erfahrung. Ich habe einmal buchstäblich neben einem Cobol-Laden gearbeitet, in dem ELSE nicht verwendet wurde, "weil es zu kompliziert war". Reductio ad absurdam.

Marquis von Lorne
quelle
@downvoter Faszinierend. Sie denken nicht, dass Programmierer in der Sprache kompetent sein sollten? Sie denken, sie sollten die Sprache künstlich lähmen? Welches ist es? Keine dritte Wahl hier.
Marquis von Lorne
1
und eine positive Abstimmung für dieses COBOL-Beispiel macht mich noch mehr froh, dass COBOL größtenteils ausgestorben ist, bevor ich mit dem Codieren angefangen habe
Mark K Cowan
1
@ MarkCowan Ich verstehe nicht warum. Mein Punkt ist über die willkürliche Einschränkung, nicht die Sprache. Die Anekdote zeigt nichts Falsches an Cobol an. Was aussterben musste, war dieser Programmierladen, und das tat es auch. Besuchen Sie die Eingeweide einer großen Bank und Sie werden feststellen, dass Cobol gesund und munter ist.
Marquis von Lorne
2

Wie in einigen der vorhandenen Antworten erwähnt (die ich ärgerlicherweise nicht kommentieren kann), besteht das Problem darin, dass x ++ ++ x unterschiedliche Werte (vor und nach dem Inkrement) auswertet, was nicht offensichtlich ist und sehr verwirrend sein kann - wenn dieser Wert verwendet wird. cdmckay schlägt mit Bedacht vor, die Verwendung des Inkrementoperators zuzulassen, jedoch nur so, dass der zurückgegebene Wert nicht verwendet wird, z. B. in einer eigenen Zeile. Ich würde auch die Standardverwendung in eine for-Schleife aufnehmen (aber nur in die dritte Anweisung, deren Rückgabewert nicht verwendet wird). Ich kann mir kein anderes Beispiel vorstellen. Da ich selbst "verbrannt" wurde, würde ich die gleiche Richtlinie auch für andere Sprachen empfehlen.

Ich bin mit der Behauptung nicht einverstanden, dass diese Überstrenge darauf zurückzuführen ist, dass viele JS-Programmierer unerfahren sind. Dies ist genau die Art des Schreibens, die typisch für "übermäßig clevere" Programmierer ist, und ich bin sicher, dass es in traditionelleren Sprachen und bei JS-Entwicklern, die einen Hintergrund in solchen Sprachen haben, viel häufiger vorkommt.

In der Nähe von Privman
quelle
1
Danke für die Antwort. Zum Kommentieren benötigen Sie einen Reputationswert von 50 oder besser. Siehe: stackoverflow.com/faq
artlung
1
@artlung: Ich bin mir dessen und der Gründe dafür bewusst. Ich sagte nur, dass es nervt :)
In der Nähe von Privman
2

Nach meiner Erfahrung hat ++ i oder i ++ nie zu Verwirrung geführt, außer beim ersten Erlernen der Funktionsweise des Operators. Es ist wichtig für die grundlegendsten Loops und While-Loops, die von einem Highschool- oder College-Kurs in Sprachen unterrichtet werden, in denen Sie den Operator verwenden können. Ich persönlich finde es besser, etwas wie das, was unten steht, zu tun und zu lesen, als etwas, bei dem sich ein ++ in einer separaten Zeile befindet.

while ( a < 10 ){
    array[a++] = val
}

Am Ende ist es eine Stilvorliebe und nichts weiter. Wichtiger ist, dass Sie, wenn Sie dies in Ihrem Code tun, konsistent bleiben, damit andere, die an demselben Code arbeiten, folgen können und nicht dieselbe Funktionalität auf unterschiedliche Weise verarbeiten müssen .

Außerdem scheint Crockford i- = 1 zu verwenden, was meiner Meinung nach schwerer zu lesen ist als --i oder i--

burdz
quelle
2

Meine 2 Cent sind, dass sie in zwei Fällen vermieden werden sollten:

1) Wenn Sie eine Variable haben, die in vielen Zeilen verwendet wird, und Sie sie bei der ersten Anweisung, die sie verwendet (oder zuletzt oder, noch schlimmer, in der Mitte), erhöhen / verringern:

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

In Beispielen wie diesem können Sie leicht übersehen, dass die Variable automatisch inkrementiert / dekrementiert wird, oder sogar die erste Anweisung entfernen. Mit anderen Worten, verwenden Sie es nur in sehr kurzen Blöcken oder dort, wo die Variable in dem Block nur in ein paar engen Anweisungen erscheint.

2) Bei mehreren ++ und - ungefähr derselben Variablen in derselben Anweisung. Es ist sehr schwer sich zu erinnern, was in solchen Fällen passiert:

result = ( ++x - --x ) * x++;

Prüfungen und professionelle Tests fragen nach Beispielen wie oben, und tatsächlich bin ich auf diese Frage gestoßen, als ich nach Dokumentation über eines davon gesucht habe, aber im wirklichen Leben sollte man nicht gezwungen sein, so viel über eine einzelne Codezeile nachzudenken.

zakmck
quelle
1

Ist Fortran eine C-ähnliche Sprache? Es hat weder ++ noch -. So schreiben Sie eine Schleife :

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

Das Indexelement i wird jedes Mal durch die Schleife durch die Sprachregeln inkrementiert. Wenn Sie um etwas anderes als 1 erhöhen möchten, zählen Sie beispielsweise um zwei rückwärts. Die Syntax lautet ...

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

Ist Python C-ähnlich? Es verwendet Bereichs- und Listenverständnisse und andere Syntaxen, um die Notwendigkeit des Inkrementierens eines Index zu umgehen:

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

Basierend auf dieser rudimentären Untersuchung von genau zwei Alternativen können Sprachdesigner ++ vermeiden und - indem sie Anwendungsfälle antizipieren und eine alternative Syntax bereitstellen.

Sind Fortran und Python weniger ein Fehlermagnet als prozedurale Sprachen mit ++ und -? Ich habe keine Beweise.

Ich behaupte, dass Fortran und Python C-ähnlich sind, weil ich noch nie jemanden getroffen habe, der fließend C spricht und der die Absicht von nicht verschleiertem Fortran oder Python nicht mit 90% Genauigkeit richtig erraten konnte.

Thomas L Holaday
quelle
1
Ja, IFortran stammt aus den 1950er Jahren, während C aus den 1970er Jahren stammt, also vielleicht nicht, dass Fortran C-artig ist. Das Beispiel von Python, dem so etwas wie der Plusplus-Operator fehlt, ist interessant. Das Iterieren über Datenstrukturen wird in Python einfacher gehandhabt, wobei Python "anders" objektorientiertes JavaScript ist. Vielleicht geht es in Crockfords Rat darum, mehr OO-ähnliche Syntax für die Iteration zu verwenden.
Artlung