What does “!--” do in JavaScript?

2019-01-20 21:26发布

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!

10条回答
贪生不怕死
2楼-- · 2019-01-20 21:29

It's the not operator followed by the in-place pre-decrementer.

So if pending was an integer with a value of 1:

val = 1;
--val; // val is 0 here
!val // evaluates to true
查看更多
甜甜的少女心
3楼-- · 2019-01-20 21:33

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.

查看更多
干净又极端
4楼-- · 2019-01-20 21:35

! 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.

查看更多
做自己的国王
5楼-- · 2019-01-20 21:36

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.

查看更多
劫难
6楼-- · 2019-01-20 21:36
if(!--pending)

means

if(0 == --pending)

means

pending = pending - 1;
if(0 == pending)
查看更多
乱世女痞
7楼-- · 2019-01-20 21:41

It merely decreases pending by one and obtains its logical complement (negation). The logical complement of any number different than 0 is false, for 0 it is true.

查看更多
登录 后发表回答