"!--" 在 JavaScript 中是做啥的?

Posted

技术标签:

【中文标题】"!--" 在 JavaScript 中是做啥的?【英文标题】:What does "!--" do in JavaScript?"!--" 在 JavaScript 中是做什么的? 【发布时间】:2016-03-23 06:26:36 【问题描述】:

我有这段代码(取自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);
                
            );
        );
    );
;

我正在努力关注它,我想我什么都理解了,除了在结尾处写着!--pending。在这种情况下,该命令的作用是什么?

编辑:我感谢所有进一步的 cmets,但这个问题已被多次回答。还是谢谢!

【问题讨论】:

你能解释一下这段代码吗,我不明白为什么要检查if (!--pending) done(null, results); 这让我想起了What is the name of the --> operator? 请注意,这里的用例可以通过 Promise 轻松解决,而不是发明我们自己的同步机制。这个函数也不能正确地进行错误处理。这就是为什么除非你有充分的理由,否则不应该推出自己的并发。 【参考方案1】:

说明

这是 2 个运算符,一个 ! 和一个 --

!--x 

所以,-- 将 x 减 1,如果 x 现在为 0(或 NaN...),! 返回 true,否则返回 false。你可能会读到这个成语,比如“我们递减 x,如果这使它为零……”

如果你想让它更具可读性,你可以:

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");trywith(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.errordisplay:block;color:red.codemin-width:10pxbodyfont-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>

Fiddle (Try Out Code)

【讨论】:

【参考方案2】:
if(!--pending)

意思

if(0 == --pending)

意思

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

【讨论】:

【参考方案3】:

!javascript NOT 运算符

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

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

【讨论】:

【参考方案4】:

那不是特殊运算符,是2个标准运算符一个接一个:

    前缀递减 (--) 逻辑非 (!)

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

【讨论】:

【参考方案5】:

这里真正的问题是!-- 两个运算符之间没有空格。

我不知道为什么人们会认为! 运算符后面不能使用空格。我认为它来自机械空白规则的严格应用,而不是常识。我见过的几乎所有编码标准都在所有一元运算符之后都禁止使用空格,但为什么呢?

如果您明确需要该空间,这就是其中之一。

考虑这段代码:

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

不仅!-- 混合在一起,而且( 也与它们发生碰撞。难怪很难说出什么与什么有关。

更多的空白使代码更清晰:

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

当然,如果您习惯了诸如“括号内没有空格”和“一元运算符后没有空格”之类的机械规则,这可能看起来有点陌生。

但是看看额外的空格是如何分组和分隔if 语句和表达式的各个部分的:你有--pending,所以-- 显然是它自己的运算符并且与@987654332 密切相关@。 (它递减pending 并返回递减的结果。)然后你将! 与它分开,所以它显然是一个不同的运算符,否定结果。最后,您将if() 包围整个表达式,使其成为if 语句。

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

此处的空格用于传达含义,而不是遵循一些机械编码标准。

【讨论】:

空白版本对我来说更具可读性。当我第一次看到这个问题时,我认为!-- 是一些我不知道的javascript 运算符。为什么不使用括号使其更加明确呢? if(!(--pending)) 没有样式指南我知道禁止使用++--,但许多do 禁止使用非必要空格,例如! 前缀运算符之后, 和非必要的括号。 一元运算符后面的空格是不鼓励的,因为它将它与它所操作的表达式分开。你希望它被一起阅读......至少恕我直言【参考方案6】:

! 反转一个值,并为您提供相反的布尔值:

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

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

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

因此,!--pending 从待处理中减去 1,然后返回其真值/假值的相反值(无论它是否为 0)。

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

是的,请遵循专业提示。这在其他编程语言中可能是一个常见的习惯用法,但对于大多数声明式 JavaScript 编程来说,这看起来很陌生。

【讨论】:

【参考方案7】:

它是 not 运算符,后跟就地预减量器。

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

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

【讨论】:

【参考方案8】:

许多答案描述了这个命令的作用,但没有描述为什么在这里这样做。

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

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

变量pending 跟踪其中有多少待处理。它以列表的长度开始,并随着每个条目的处理而向下计数。

这些条目可能会被乱序处理,这就是为什么需要倒计时而不是仅仅使用简单的循环。当所有条目被处理后,回调done被调用以通知原始调用者这一事实。

在对done 的第一次调用中以return 开头,不是因为我们想要返回一个值,而只是为了让函数在该点停止执行。删除 return 并将替代代码放在 else 中会更简洁。

【讨论】:

【参考方案9】:

它只是将pending 减一并获得其逻辑补码(否定)。任何不同于 0 的数字的逻辑补码是 false,对于 0,它是 true

【讨论】:

【参考方案10】:

这是一个简写。

! 是“不”。

-- 递减一个值。

所以!--会检查对减值结果求反得到的值是否为假。

试试这个:

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

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

旁注: !x-- 会先检查 x 是否为假,然后递减。

【讨论】:

我想你的意思是说“!-- 返回对递减值结果的否定。”只有外部代码,例如console.log(),检查其内容是否真实。

以上是关于"!--" 在 JavaScript 中是做啥的?的主要内容,如果未能解决你的问题,请参考以下文章

FileUpload

在引用js文件timestamp作用是啥?

canvas中怎么绘制一个扇形?四分之一圆.

JS中如何判断他输入了回车键~!!!

Jquery中"$(document).ready(function(){ })"函数的使用详解

关于window.parent的浏览器兼容问题