381 votes

Ce n' "!--" faire en JavaScript?

J'ai ce morceau de code (prises à partir 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);
                }
            });
        });
    });
};

Je suis en train de le suivre, et je crois que je comprends tout sauf vers la fin où il est dit !--pending. Dans ce contexte, quelle est la commande?

Edit: j'apprécie tous les autres commentaires, mais la question a été posée de nombreuses fois. Merci quand même!

543voto

TbWill4321 Points 5334

! inverse une valeur, et vous donne le contraire booléen:

!true == false
!false == true
!1 == false
!0 == true

--[value] soustrait un (1) à partir d'un nombre, puis retourne ce nombre à être travaillé avec:

var a = 1, b = 2;
--a == 0
--b == 1

Donc, !--pending soustrait l'un de l'attente, puis renvoie l'inverse de ses truthy/falsy valeur (qu'il soit ou non 0).

pending = 2; !--pending == false 
pending = 1; !--pending == true
pending = 0; !--pending == false

Et oui, suivez le ProTip. Cela peut être un idiome commun dans d'autres langages de programmation, mais pour la plupart des déclaratif de programmation JavaScript, cela ressemble tout à fait étranger.

151voto

Amit Points 1

Ce n'est pas un opérateur spécial, c'est de 2 opérateurs standard, l'un après l'autre:

  1. Un préfixe de décrémentation (--)
  2. Un non logique (!)

Cela provoque pending à être décrémenté et puis testé pour voir si c'est le zéro.

109voto

Stig Hemmer Points 2175

Un certain nombre de réponses décrit ce que cette commande fonctionne, mais pas pourquoi il est fait de cette façon là.

Je viens de la C monde, et j'ai lu !--pending "compte à rebours pending et de vérifier si elle est égale à zéro", sans vraiment y penser. C'est un idiome que je pense que les programmeurs dans les mêmes langues se doit de connaître.

La fonction utilise readdir pour obtenir une liste des fichiers et sous-répertoires, qui, je, collectivement, les appeler des "entrées".

La variable pending garde une trace de la façon dont beaucoup de ces vestiges à être traitées. Il commence comme la longueur de la liste, et compte vers zéro que chaque entrée est traitée.

Ces entrées peuvent être traitées hors de l'ordre, qui est pourquoi il est nécessaire de compter vers le bas, plutôt que de simplement en utilisant une simple boucle. Lorsque toutes les entrées sont traitées le rappel done est appelé à informer l'appelant d'origine de ce fait.

Dans le premier appel à done sont précédées return, non pas parce que nous voulons retourner une valeur, mais simplement pour rendre la fonction d'arrêt de l'exécution à ce point. Il aurait été plus propre code d'abandonner l' return et de mettre l'alternative en else.

36voto

Lucas Points 1047

C'est une abréviation.

! "n'est pas".

-- décrémente une valeur.

Donc, !-- vérifie si la valeur obtenue à partir de la négation de la raison de décrémenter une valeur est false.

Essayez ceci:

var x = 2;
console.log(!--x);
console.log(!--x);

La première est fausse, puisque la valeur de x est 1, le deuxième est vrai, puisque la valeur de x est de 0.

Note de côté: !x-- serait de vérifier si x est faux d'abord, et ensuite de décrémentation.

31voto

Sterling Archer Points 8480

! du JavaScript PAS de l'opérateur

-- est un pré-décrémentation de l'opérateur. Donc,

x = 1;
if (!x) // false
if (!--x) // becomes 0 and then uses the NOT operator,
          // which makes the condition to be true

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X