我有这样一段代码(来自这个问题):

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);
                }
            });
        });
    });
};

我试着跟着看,我想我什么都懂了,除了接近结尾的地方说!——待定。在这个上下文中,该命令做什么?

编辑:我感谢所有进一步的评论,但这个问题已经回答过很多次了。谢谢!


当前回答

! 反转一个值,并给出相反的布尔值:

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

——[value]从一个数字中减去1(1),然后返回要处理的数字:

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

因此,!——pending从pending中减去1,然后返回它的真值/假值的相反值(不管它是否为0)。

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

是的,遵循ProTip。这可能是其他编程语言中常见的习惯用法,但对于大多数声明式JavaScript编程来说,这看起来相当陌生。

其他回答

! JavaScript是NOT操作符吗

——是一个预自减运算符。所以,

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

这不是一个特殊运算符,它是两个标准运算符一个接一个:

前缀递减(——) 一个合乎逻辑的不(!)

这会导致pending递减,然后测试它是否为零。

它只是把未决减一,而得到它的逻辑补足(否定)。任何不同于0的数的逻辑补均为假,因为0为真。

这是一种速记。

! “不是”。

——递减一个值。

因此!——检查从一个值的递减结果求负得到的值是否为假。

试试这个:

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

第一个为假,因为x的值是1,第二个为真,因为x的值是0。

注: x——首先检查x是否为假,然后递减它。

它是not运算符后面跟着原地预减数。

如果pending是一个值为1的整数:

val = 1;
--val; // val is 0 here
!val // evaluates to true