什么“! – ”在JavaScript中做什么?

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

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 在这种情况下,这个命令是做什么的?

编辑:我感谢所有进一步的意见,但这个问题已经回答了很多次。 不pipe怎么说,还是要谢谢你!

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

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

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

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

所以, !--pending减去一个,然后返回与它的真/假值相反的值(不pipe它是否为0 )。

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

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

这不是一个特殊的运营商,它是一个接一个的标准运营商:

  1. 前缀递减( --
  2. 逻辑不是( !

这会导致pending递减,然后testing是否为零。

大量的答案描述这个命令的作用,但不是为什么这样做。

我来自C世界,我读了!--pending为“倒计时,并检查是否为零”,而没有真正考虑它。 这是一个我认为类似的语言程序员应该知道的习惯用语。

该函数使用readdir来获取文件和子目录的列表,我将统称为“entries”。

pending的variableslogging了这些剩余处理的数量。 它以列表的长度开始,并在处理每个条目时向下计数到零。

这些条目可能不按顺序处理,这就是为什么有必要倒计时而不是简单地使用一个简单的循环。 当所有的条目都被处理后,callbackdone被调用来通知原来的调用者这个事实。

在第一个调用done前面加上了return ,并不是因为我们想要返回一个值,而仅仅是为了让这个函数在那个时候停止执行。 这将是更清晰的代码,以减lessreturn并把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 

说明

这是2个操作员,一个!--

 !--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("<br>"),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} 
 <!-- This is an example of the above, you can read this, but it is not needed for `!--` --><span class="result result-template"> //=> unknown </span> <h2>Edit This Code:</h2><code><span class="code">x = 1</span><br><span class="code">!--x</span><br><span class="code"> x </span><br></code> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

它只是减less一个,并得到它的逻辑补(否定)。 任何不同于0的数字的逻辑补码都是false ,因为0是true

这里真正的问题是两个运营商之间缺乏空间!--

我不知道为什么人们在他们的脑海中得到这样的结果! 运营商。 我认为它来自机械空白规则的僵化应用,而不是常识。 几乎所有我看过的编码标准都禁止在所有一元运算符之后使用空格,但是为什么呢?

如果有的话你明显需要这个空间,这是一个。

考虑下面这段代码:

 if (!--pending) done(null, results); 

不仅是! 并且--混在一起,你也知道了(抨击过它们。难怪很难说出与什么相关的东西。

多一点的空白使得代码更加清晰:

 if( ! --pending ) done( null, results ); 

当然,如果你习惯了像“没有空间内的空间”和“一元操作员之后没有空间”这样的机械规则,这可能看起来有些异类。

但是看看额外的空白组是如何将if语句和expression式的各个部分分开的:你已经有了,所以--显然是它自己的操作符,并且与pending --pending紧密联系在一起。 (递减pending并返回递减的结果。)然后你已经得到了! 与之分开,所以显然是一个独特的运算符,否定了结果。 最后, if()围绕整个expression式使其成为一个if语句,那么你已经得到了。

是的,我删除了if(之间的空格,因为( 属于 if 。这个(不是某种(!--语法的一部分),因为它看起来是在原始的, if语句本身的语法。

这里的空格用来expression意思 ,而不是遵循一些机械编码标准。

Interesting Posts