What does “!–” do in JavaScript?

What does “!–” do in JavaScript?

I have this piece of code (taken from this 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);
}
});
});
});
};

I’m trying to follow it, and I think I understand everything except for near the end where it says !–pending. In this context, what does that command do?
Edit: I appreciate all the further comments, but the question has been answered many times. Thanks anyway!

Solutions/Answers:

Solution 1:

! inverts a value, and gives you the opposite boolean:

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

--[value] subtracts one (1) from a number, and then returns that number to be worked with:

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

So, !--pending subtracts one from pending, and then returns the opposite of its truthy/falsy value (whether or not it’s 0).

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

And yes, follow the ProTip. This may be a common idiom in other programming languages, but for most declarative JavaScript programming this looks quite alien.

Solution 2:

That’s not a special operator, it’s 2 standard operators one after the other:

  1. A prefix decrement (--)
  2. A logical not (!)

This causes pending to be decremented and then tested to see if it’s zero.

Solution 3:

A number of answers describes what this command does, but not why it is done that way here.

I come from the C world, and I read !--pending as “count down pending and check if it is zero” without really thinking about it. It is an idiom that I think programmers in similar languages should know.

The function uses readdir to get a list of files and subdirectories, which I will collectively call “entries”.

The variable pending keeps track of how many of these remains to be processed. It starts out as the length of the list, and counts downward towards zero as each entry is processed.

These entries may be processed out of order, which is why it is necessary to count down rather than just using a simple loop. When all the entries have been processed the callback done is called to notify the original caller of this fact.

In the first call to done is prepended with return, not because we want to return a value, but simply to make the function stop executing at that point. It would have been cleaner code to drop the return and put the alternative in an else.

Solution 4:

It’s a shorthand.

! is “not”.

-- decrements a value.

So !-- checks if the value obtained from negating the result of decrementing a value is false.

Try this:

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

The first is false, since the value of x is 1, the second is true, since the value of x is 0.

Side note:
!x-- would check if x is false first, and then decrement it.

Solution 5:

! is the JavaScript NOT operator

-- is a pre-decrement operator. So,

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

Solution 6:

if(!--pending)

means

if(0 == --pending)

means

pending = pending - 1;
if(0 == pending)