Ich habe diesen Code (aus dieser Frage entnommen ):
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err)
return done(err);
var pending = list.length;
if (!pending)
return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending)
done(null, results);
});
} else {
results.push(file);
if (!--pending)
done(null, results);
}
});
});
});
};
Ich versuche, ihm zu folgen, und ich glaube, ich verstehe alles, außer gegen Ende, wo es heißt !--pending
. Was macht dieser Befehl in diesem Zusammenhang?
Edit: Ich freue mich über alle weiteren Kommentare, aber die Frage wurde schon oft beantwortet. Danke trotzdem!
javascript
decrement
prefix-operator
not-operator
Kieran E.
quelle
quelle
!~--[value] ^ true
Ich nenne Code wie diesen "Job Security"-->
Betreiber?Antworten:
!
Invertiert einen Wert und gibt Ihnen den entgegengesetzten Booleschen Wert:--[value]
subtrahiert eins (1) von einer Zahl und gibt dann die Zahl zurück, mit der gearbeitet werden soll:Also,
!--pending
subtrahiert man aus schwebenden und kehrt dann das Gegenteil von seiner truthy / falsy Wert (ob oder nicht es ist0
).Und ja, folgen Sie dem ProTip. Dies mag in anderen Programmiersprachen eine gängige Redewendung sein, aber für die meisten deklarativen JavaScript-Programme sieht dies ziemlich fremd aus.
quelle
--
nur auf Variablen wirkt; Sie können es im Allgemeinen nicht auf Werte anwenden.validSimpleAssignmentTarget
s, um genau zu sein. Dies umfasst Bezeichnerreferenzen und Eigenschaftsreferenzen.--0
und--1
wird nicht funktionieren. Numerische Literale sind kein gültiger Ausdruck auf der linken Seitei > -1
alsi--
(und übrigens hast du es vergesseni = init() - 1
). Dafür sind Redewendungen da ... und jeder Programmierer sollte sie lernen.Das ist kein spezieller Operator, es sind 2 Standardoperatoren nacheinander:
--
)!
)Dies führt
pending
dazu, dass dekrementiert und dann getestet wird , um festzustellen, ob es Null ist.quelle
if(pending === 1)
?if( pending === 1 ) { done... } else { pending = pending - 1; }
.Eine Reihe von Antworten beschreibt, was dieser Befehl tut, aber nicht, warum er hier so ausgeführt wird.
Ich komme aus der C-Welt und lese
!--pending
als "Countdownpending
und überprüfe, ob es Null ist", ohne wirklich darüber nachzudenken. Es ist eine Redewendung, die Programmierer in ähnlichen Sprachen meiner Meinung nach kennen sollten.Die Funktion verwendet
readdir
, um eine Liste von Dateien und Unterverzeichnissen zu erhalten, die ich zusammen "Einträge" nennen werde.Die Variable
pending
verfolgt, wie viele davon noch verarbeitet werden müssen. Es beginnt als Länge der Liste und zählt bei jeder Verarbeitung nach unten in Richtung Null.Diese Einträge können außerhalb der Reihenfolge verarbeitet werden, weshalb ein Countdown erforderlich ist, anstatt nur eine einfache Schleife zu verwenden. Wenn alle Einträge verarbeitet wurden, wird der Rückruf
done
aufgerufen, um den ursprünglichen Anrufer über diese Tatsache zu informieren.Im ersten Aufruf von
done
wird nicht vorangestelltreturn
, nicht weil wir einen Wert zurückgeben möchten, sondern einfach, damit die Funktion an diesem Punkt nicht mehr ausgeführt wird. Es wäre sauberer gewesen, den Code fallen zu lassenreturn
und die Alternative in einen zu setzenelse
.quelle
!--pending
viele Linters und Stilrichtlinien fehlschlagen wird, da die Kontroverse besteht . Das reicht mir zu sagen, dass es wahrscheinlich nicht idiomatisch ist (unabhängig davon, ob die Alternative "besser" ist).int
zubool
implizit, und hat absolut nichts mit der Nutzung zu tun!--
.Es ist eine Abkürzung.
!
ist nicht".--
dekrementiert einen Wert.!--
Überprüft also , ob der Wert, der durch Negieren des Ergebnisses der Dekrementierung eines Werts erhalten wird, falsch ist.Versuche dies:
Der erste ist falsch, da der Wert von x 1 ist, der zweite ist wahr, da der Wert von x 0 ist.
Randnotiz:
!x--
würde zuerst prüfen, ob x falsch ist, und es dann dekrementieren.quelle
!
Pre-Fix, während Pre-Fix eine niedrigere Priorität hat. JavaScript Operator Vorrangvar x = 2; console.log(!x--); console.log(!x--); console.log(!x--);
). Während das Post-Fix--
möglicherweise zuerst ausgeführt wird, ist sein Rückgabewert der Wert der Variablen vor dem Dekrementieren ( Decrement Opperator ).!--
Gibt die Negation des Ergebnisses der Dekrementierung eines Werts zurück." Nurconsole.log()
externer Code, z. B. , prüft, ob sein Inhalt wahr ist.!
ist der JavaScript NOT- Operator--
ist ein Operator vor dem Dekrementieren. Damit,quelle
--
Operator mit einer Konstanten arbeiten könnte ... vielleicht meinten Sie--x
stattdessen--0
?meint
meint
quelle
if(0 == pending)
wegen des Potenzials für Tippfehler.if(0 = pending)
ist ein Syntaxfehler.if(pending = 0)
ist eine Aufgabe, die im fertigen Code zu verwirrendem Verhalten führt.if(0 = pending)
kein Syntaxfehler - es wird gut analysiert - sondern ein Referenzfehler, da er0
nicht zuweisbar ist (siehe ECMA-262 (6. Ausgabe), Abschnitt 12.14.1).Es ist der Nicht-Operator, gefolgt vom In-Place-Vordekrementierer.
Wenn also
pending
eine Ganzzahl mit dem Wert 1 wäre:quelle
Es nimmt lediglich um
pending
eins ab und erhält seine logische Ergänzung (Negation). Das logische Komplement einer beliebigen Zahlfalse
, die sich von 0 unterscheidet, ist für 0true
.quelle
Erläuterung
Dies sind 2 Operatoren, a
!
und a--
Also
--
dekrementiert x um 1, dann!
gibt true zurück, wenn x jetzt 0 ist (oder NaN ...), false, wenn dies nicht der Fall ist. Sie könnten diese Redewendung so etwas wie "Wir dekrementieren x und wenn das Null macht ..." lesen.Wenn Sie es lesbarer machen möchten, können Sie:
Versuch es:
Geige (Code ausprobieren)
quelle
Das eigentliche Problem hierbei ist das Fehlen eines Leerzeichens zwischen den beiden Operatoren
!
und--
.Ich weiß nicht, warum die Leute es in ihren Köpfen verstehen, dass man nach dem
!
Operator niemals ein Leerzeichen verwenden kann . Ich denke, es kommt von der starren Anwendung mechanischer Leerzeichenregeln anstelle des gesunden Menschenverstandes. Fast jeder Codierungsstandard, den ich gesehen habe, verbietet Leerzeichen nach allen unären Operatoren, aber warum?Wenn es jemals einen Fall gab, in dem Sie diesen Platz eindeutig benötigen , ist dies einer.
Betrachten Sie diesen Code:
Nicht nur
!
und--
püriert, du hast das auch(
gegen sie geschlagen. Kein Wunder, dass es schwer zu sagen ist, was mit was verbunden ist.Ein bisschen mehr Leerzeichen macht den Code viel klarer:
Sicher, wenn Sie an mechanische Regeln wie "kein Platz in Parens" und "kein Platz nach einem unären Operator" gewöhnt sind, scheint dies etwas fremd zu sein.
Aber schauen Sie sich an, wie das zusätzliche Leerzeichen die verschiedenen Teile der
if
Anweisung und des Ausdrucks gruppiert und trennt : Sie haben--pending
, also--
ist das eindeutig sein eigener Operator und eng mit ihm verbundenpending
. (Es dekrementiertpending
und gibt das dekrementierte Ergebnis zurück.) Dann haben Sie das davon!
getrennt, so dass es offensichtlich ein eindeutiger Operator ist, der das Ergebnis negiert. Schließlich haben Sie ,if(
und)
den gesamten Ausdruck umgibt , um es eine machenif
Aussage.Und ja, entfernte ich den Raum zwischen
if
und(
, weil das(
gehört zu demif
. Dies(
ist nicht Teil einer(!--
Syntax, wie es im Original zu sein scheint, der(
if-Teil der Syntax derif
Anweisung selbst.Das Leerzeichen dient hier dazu, die Bedeutung zu kommunizieren , anstatt einem mechanischen Codierungsstandard zu folgen.
quelle
!--
es sich um einen Javascript-Operator handelte, den ich nicht kannte. Warum nicht Klammern verwenden, um es noch deutlicher zu machen?if(!(--pending))
++
oder--
, aber viele tun verbieten unter Verwendung von nicht-essentielle Räume wie nach dem!
Präfix - Operator, und nicht wesentliche Klammern.