J'ai ce morceau de code (tiré de cette question ):
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);
}
});
});
});
};
J'essaie de le suivre, et je pense que je comprends tout, sauf vers la fin où il est dit !--pending
. Dans ce contexte, que fait cette commande?
Edit: J'apprécie tous les autres commentaires, mais la question a été répondue à plusieurs reprises. Merci quand même!
!~--[value] ^ true
J'appelle un code comme celui-ci "sécurité d'emploi"-->
opérateur?Réponses:
!
inverse une valeur et vous donne le booléen opposé:--[value]
soustrait un (1) d'un nombre, puis renvoie ce nombre avec lequel travailler:Donc,
!--pending
soustrait un de l'attente, puis retourne le contraire de sa valeur de vérité / fausse (que ce soit ou non0
).Et oui, suivez le ProTip. Cela peut être un idiome courant dans d'autres langages de programmation, mais pour la plupart des programmes JavaScript déclaratifs, cela semble assez étranger.
la source
--
n'agit que sur les variables; vous ne pouvez pas l'appliquer aux valeurs en général.validSimpleAssignmentTarget
s, pour être exact. Cela inclut les références d'identifiant et les références de propriété.--0
et--1
ne fonctionnera pas. Les littéraux numériques ne sont pas une expression valide du côté gauchei > -1
chose quei--
(et d'ailleurs vous avez oubliéi = init() - 1
). C'est à cela que servent les idiomes… et chaque programmeur devrait les apprendre.Ce n'est pas un opérateur spécial, c'est 2 opérateurs standard l'un après l'autre:
--
)!
)Cela provoque
pending
une décrémentation, puis un test pour voir s'il est nul.la source
if(pending === 1)
?if( pending === 1 ) { done... } else { pending = pending - 1; }
.Un certain nombre de réponses décrivent ce que fait cette commande, mais pas pourquoi elle est effectuée de cette façon ici.
Je viens du monde C, et je lis
!--pending
comme "compte à rebourspending
et vérifie si c'est zéro" sans vraiment y penser. C'est un idiome que je pense que les programmeurs dans des langages similaires devraient connaître.La fonction utilise
readdir
pour obtenir une liste de fichiers et de sous-répertoires, que j'appellerai collectivement «entrées».La variable
pending
garde la trace du nombre de ceux qui restent à traiter. Il commence comme la longueur de la liste et compte vers le bas vers zéro lorsque chaque entrée est traitée.Ces entrées peuvent être traitées dans le désordre, c'est pourquoi il est nécessaire de décompter plutôt que de simplement utiliser une simple boucle. Lorsque toutes les entrées ont été traitées, le rappel
done
est appelé pour informer l'appelant d'origine de ce fait.Dans le premier appel à
done
est précédé dereturn
, non pas parce que nous voulons retourner une valeur, mais simplement pour arrêter l'exécution de la fonction à ce point. Il aurait été préférable de supprimer le codereturn
et de mettre l'alternative dans unelse
.la source
!--pending
échouera de nombreux linters et directives de style. Cela me suffit pour dire que ce n'est probablement pas idiomatique (que l'alternative soit "meilleure").int
pasbool
implicitement, et n'a absolument rien à voir avec l'utilisation de!--
.C'est un raccourci.
!
n'est pas".--
décrémente une valeur.!--
Vérifie donc si la valeur obtenue en annulant le résultat de la décrémentation d'une valeur est fausse.Essaye ça:
La première est fausse, car la valeur de x est 1, la seconde est vraie, car la valeur de x est 0.
Remarque:
!x--
vérifierait d'abord si x est faux, puis le décrémenterait.la source
!
, tandis que le préfixe a une priorité plus faible.var x = 2; console.log(!x--); console.log(!x--); console.log(!x--);
). Alors que le post-fix--
peut s'exécuter en premier, sa valeur de retour est la valeur de la variable avant décrémentation ( Decrement Opperator ).!--
renvoie la négation du résultat de la décrémentation d'une valeur". Seul le code extérieur, tel queconsole.log()
, vérifie si son contenu est véridique.!
est l' opérateur JavaScript NOT--
est un opérateur de pré-décrémentation. Donc,la source
--
opérateur pourrait travailler avec une constante ... peut-être que vous vouliez dire à la--x
place de--0
?veux dire
veux dire
la source
if(0 == pending)
raison du potentiel de fautes de frappe.if(0 = pending)
est une erreur de syntaxe.if(pending = 0)
est une affectation qui provoquera un comportement déroutant dans le code fini.if(0 = pending)
n'est pas une erreur de syntaxe - ça analyse bien - mais une erreur de référence car elle0
n'est pas attribuable (réf ECMA-262 (6e éd) sec 12.14.1).C'est l'opérateur not suivi du pré-décrémenteur en place.
Donc, si
pending
était un entier avec une valeur de 1:la source
Il diminue simplement
pending
de un et obtient son complément logique (négation). Le complément logique de tout nombre différent de 0 estfalse
, pour 0, il l'esttrue
.la source
Explication
Il s'agit de 2 opérateurs, a
!
et a--
Ainsi, le
--
décrémente x de 1, puis le!
retourne vrai si x est maintenant 0 (ou NaN ...), faux s'il ne l'est pas. Vous pourriez lire cet idiome quelque chose comme "nous décrémentons x et si cela le rend nul ..."Si vous souhaitez le rendre plus lisible, vous pouvez:
Essaye le:
Fiddle (Try Out Code)
la source
Le vrai problème ici est le manque d'espace entre les deux opérateurs
!
et--
.Je ne sais pas pourquoi les gens pensent que vous ne pouvez jamais utiliser un espace après l'
!
opérateur. Je pense que cela vient d'une application rigide des règles mécaniques des espaces blancs au lieu du bon sens. Presque toutes les normes de codage que j'ai vues interdisent les espaces après tous les opérateurs unaires, mais pourquoi?S'il y a jamais eu un cas où vous avez clairement besoin de cet espace, celui-ci en est un.
Considérez ce morceau de code:
Non seulement sont
!
et--
purée ensemble, vous avez que(
a claqué contre eux aussi. Pas étonnant qu'il soit difficile de dire ce qui est connecté à quoi.Un peu plus d'espace rend le code beaucoup plus clair:
Bien sûr, si vous êtes habitué aux règles mécaniques comme "pas d'espace à l'intérieur des parens" et "pas d'espace après un opérateur unaire", cela peut sembler un peu étranger.
Mais regardez comment les espaces blancs supplémentaires regroupent et séparent les différentes parties de l'
if
instruction et de l'expression: vous avez--pending
, donc--
c'est clairement son propre opérateur et est étroitement lié àpending
. (Il décrémentepending
et renvoie le résultat décrémenté.) Ensuite, vous avez le!
séparé de cela, c'est donc évidemment un opérateur distinct, annulant le résultat. Enfin, vous avezif(
et)
entourez toute l'expression pour en faire uneif
déclaration.Et oui, j'ai supprimé l'espace entre
if
et(
, car le(
appartient auif
. Cela(
ne fait pas partie d'une sorte de(!--
syntaxe, comme il semble être dans l'original, la(
partie if de la syntaxe de l'if
instruction elle-même.L'espace blanc ici sert à communiquer la signification , au lieu de suivre une norme de codage mécanique.
la source
!--
s'agissait d'un opérateur javascript que je ne connaissais pas. Pourquoi ne pas utiliser des parenthèses pour le rendre encore plus explicite?if(!(--pending))
++
ou--
, mais beaucoup n'interdisent l' utilisation des espaces non essentiels tels que après l' opérateur préfixe et les parenthèses non essentiels.!