我有这段代码(取自这个问题):
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); } }); }); }); };
我正在努力遵循它,我想我理解除了接近结尾的所有内容!--pending
.在这种情况下,该命令的作用是什么?
编辑:我感谢所有进一步的评论,但这个问题已被多次回答.不管怎么说,还是要谢谢你!
!
反转一个值,并给你相反的布尔值:
!true == false !false == true !1 == false !0 == true
--[value]
从数字中减去一(1),然后返回要使用的数字:
var a = 1, b = 2; --a == 0 --b == 1
因此,!--pending
从pending中减去一个,然后返回其truthy/falsy值的相反值(无论是否为0
).
pending = 2; !--pending == false pending = 1; !--pending == true pending = 0; !--pending == false
是的,请关注ProTip.这可能是其他编程语言中常见的习惯用语,但对于大多数声明性JavaScript编程而言,这看起来很陌生.
这不是一个特殊的运营商,它是一个接一个的2个标准运营商:
前缀减量(--
)
逻辑not(!
)
这导致pending
递减,然后测试它是否为零.
许多答案描述了这个命令的作用,但不是为什么在这里这样做.
我来自C世界,我读!--pending
作"倒数pending
并检查它是否为零"而没有真正考虑它.我认为类似语言的程序员应该知道这是一个成语.
该函数用于readdir
获取文件和子目录的列表,我将统称为"条目".
变量pending
跟踪要处理的剩余数量.它从列表的长度开始,并在处理每个条目时向下计数到零.
这些条目可能无序处理,这就是为什么有必要倒计时而不是仅使用简单的循环.当处理完所有条目后,将调用回调done
以通知原始调用者这一事实.
在第一次调用done
被换成了return
,不是因为我们要返回一个值,而仅仅是为了使功能停止在该点执行.如果放弃return
并将备选方案放入其中,那将是更清晰的代码else
.
这是一个速记.
!
不是".
--
递减一个值.
因此,!--
检查从否定递减值的结果获得的值是否为假.
试试这个:
var x = 2; console.log(!--x); console.log(!--x);
第一个是假,因为x的值是1,第二个是真的,因为x的值是0.
旁注:
!x--
首先检查x是否为假,然后递减.
!
是JavaScript NOT运算符
--
是一个预减量运算符.所以,
x = 1; if (!x) // false if (!--x) // becomes 0 and then uses the NOT operator, // which makes the condition to be true
if(!--pending)
手段
if(0 == --pending)
手段
pending = pending - 1; if(0 == pending)
它是非操作符,后跟就地预先递减器.
所以如果pending
是一个值为1的整数:
val = 1; --val; // val is 0 here !val // evaluates to true
它只减少pending
一个并获得其逻辑补充(否定).任何不同于0的数字的逻辑补码是false
0,它是0 true
.
这是2个运营商,a !
和a--
!--x
所以,这会使x减1,并检查它是否是布尔值.
如果您想让它更具可读性,您可以:
var x = 1 x = x - 1 if(!x){ //=> true console.log("I understand `!--` now!") } x //=> 0试试看:
/* This is an example of the above, you can read this, but it is not needed for !-- */function interactive(a){$("span.code").keydown(function(e){if(13==(e.keyCode||e.which)){var t=$(this);t.clone().html("code").insertAfter(t.next().next()).show().focus().after(template.clone().removeClass("result-template").show()).next().after("
"),interactive(),e.preventDefault()}}).keyup(function(e){13!=(e.keyCode||e.which)&&run()})}var template=$(".result-template").hide(),code=$("span.code");code.attr("contenteditable","true").each(function(e,t){template.clone().removeClass("result-template").insertAfter(t)}),interactive(),$.fn.reduce=[].reduce;function run(){var b=!1,context={};$("span.code").each(function(){var a=$(this),res=a.next().show().removeClass("error");try{with(context)res.html(b?"":" //=> "+eval(a.text()))}catch(e){b=e,res.html(" Error: "+b.message).addClass("error")}})};run();
/* This is an example of the above, you can read this, but it is not needed for !-- */span.result.error{display:block;color:red}.code{min-width:10px}body{font-family:Helvetica,sans-serif}
//=> unknown Edit This Code:
x = 1
!--x
x
这里真正的问题是缺乏两家运营商之间的空间!
和--
.
我不知道为什么人们会在他们的头脑中得到它,你不能在!
操作员之后使用空间.我认为它来自机械空白规则的严格应用,而不是常识.几乎我看到的所有编码标准都禁止所有一元运算符之后的空格,但为什么呢?
如果有一种情况你明显需要这个空间,那就是一个.
考虑一下这段代码:
if (!--pending) done(null, results);
不仅是!
和--
捣碎在一起,你(
也会抨击它们.难怪很难说出与什么相关的东西.
更多的空格使代码更加清晰:
if( ! --pending ) done( null, results );
当然,如果你习惯于机械规则,比如"没有空间内的空间"和"一元经营者之后没有空间",这可能看起来有点异国情调.
但是看一下额外的空格如何组合并分离if
语句和表达式的各个部分:你已经得到了--pending
,所以--
它显然是它自己的运算符并且紧密相连pending
.(它递减pending
并返回递减的结果.)然后你已经将!
它与之分开,所以它显然是一个独特的运算符,否定了结果.最后,你已经得到if(
并)
围绕整个表达式,使其成为一个if
陈述.
是的,我删除之间的空间if
和(
,因为(
所属的if
.这(
不是某种(!--
语法的一部分,因为它似乎是原始语句本身(
语法的if部分if
.
这里的空白用于传达意义,而不是遵循一些机械编码标准.