当前位置:  开发笔记 > 编程语言 > 正文

JavaScript中有"! - "做什么?

如何解决《JavaScript中有"!-"做什么?》经验,为你挑选了10个好方法。

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

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.在这种情况下,该命令的作用是什么?

编辑:我感谢所有进一步的评论,但这个问题已被多次回答.不管怎么说,还是要谢谢你!



1> TbWill4321..:

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

!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编程而言,这看起来很陌生.


ProTip™:永远不要在你的代码中这样做,这太荒谬了.
`--0`和`--1`不起作用.数字文字不是有效的左侧表达式
这并没有提到` - `只对变量起作用; 一般情况下,你不能将它应用于值.
@deltab:`validSimpleAssignmentTarget,确切地说.这包括标识符引用和属性引用.
@Pharap:呃,我解析那个`i> -1`的东西比`i - `更麻烦(顺便说一句,你忘了`i = init() - 1`).这就是成语所代表的......每个程序员都应该学习它们.
坦率地说,整个讨论都很荒谬.无论克罗克福德说什么,都没有理由避免使用` - `或`++`,这些自古以来就被用于其他语言.没有任何理由避免将操作符放在一起,无论是`num + +"strNum"`,还是" - >"(喘气)或其他任何东西.如果程序员不了解这些操作符或它们的组合含义,那么让他们学习语言.没有理由使用这种语言的愚蠢版本,因为一些开发人员并没有费心去学习它.`! - `紧凑,可读,不易出错.
@Bergi对我来说这类似于'A && B || C && D`.编译器和开发人员的一半可以立即清楚操作的顺序和意图.为了向所有开发人员说清楚,添加括号:`!( - pending)`
@Bergi if条件中的非纯表达式听起来像是'gotcha'等待发生.是的,我会反对那个古老的`while`成语.除了表达式是非纯的,您使用的是数字类型,就好像它是一个布尔值.它会更可读,因为`while(i> -1){/*body*/ - i; 你甚至可以使用`for`循环:`for(int i = init(); i> -1; --i){/*body*/}` - 没有歧义,完全可读.
@Pharap:当然我理解它,毕竟这是一个微不足道的循环.我只是说我发现它比成语更难理解,这更简洁,需要更少的心灵努力.是的,明确可以让那些不熟悉编程的人更容易,但是对于其他人来说,你应该使用这个成语.
也许关于循环条件的详细讨论应该转移到聊天中,而不是在关于一元运算符的问题的评论中挂出.(JavaScript中的@Agop)
@Maurycy我们在这里谈论Javascript.当然你的意思是"简洁!==更具可读性".:)
@NaftuliTzviKay怎么样?你更喜欢`--pending == 0`吗?
@Bergi我想我们必须同意不同意,因为我认为`for`循环更具可读性,而'while`'aciomom'更加神秘.
@torazaburo除非你的变量从0开始,否则不会出错,在这种情况下它永远不会运行.简洁!=更加灵活,即使对于有经验的程序员也是如此.如果你管理的代码充满了不寻常的代码片段,如`` - ``或`` - >``那么很明显你迟早会学会快速解析它们,但从我的经验来看,清晰明确的代码总是比隐含和充满怪癖更容易阅读,因为即使你有更多的行来阅读它也更容易理解,你的思想不会被调用``decode(" - >")``占用.

2> Amit..:

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

    前缀减量(--)

    逻辑not(!)

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


@KieranE,它不是,它的简写完全打破了"可读性为王"的规则.
@KieranE不是要优越,而是与众不同.它会变量变量(将其减1)然后使用新值进行测试
我对这一点肯定是新手,但为什么这比使用`if(pending === 1)`更优越呢?
@KieranE,相当于`if(pending === 1){done ...} else {pending = pending - 1; }`.
@CompuChip它实际上看起来像 - 在任何情况下都要做,所以代码更像是:if(!pending){--pending; 等}}其他{ - 开; 这是基于https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

3> Stig Hemmer..:

许多答案描述这个命令的作用,但不是为什么在这里这样做.

我来自C世界,我读!--pending作"倒数pending并检查它是否为零"而没有真正考虑它.我认为类似语言的程序员应该知道这是一个成语.

该函数用于readdir获取文件和子目录的列表,我将统称为"条目".

变量pending跟踪要处理的剩余数量.它从列表的长度开始,并在处理每个条目时向下计数到零.

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

在第一次调用done被换成了return,不是因为我们要返回一个值,而仅仅是为了使功能停止在该点执行.如果放弃return并将备选方案放入其中,那将是更清晰的代码else.


@Bergi它是C世界中一个着名的成语,但它不是*惯用的Javascript.对于任何给定的子表达式,不同的生态系统将有各种不同的,不相容的习语,那里的"完成".使用来自"外国"语言的习语是一种相当糟糕的代码味道.
Javascript社区的很大一部分,包括有影响力的领导者,如道格拉斯克罗克福德,主张避免一元递增和减少运营商**完全**.我不打算在这里争论他们是否正确; 我的意图只是要指出,因为争议存在,像`! - pending`这样的代码将失败许多短信和风格指南.这足以让我说它可能不是惯用的(无论替代方案是否"更好").
@Peteris:这是所有C语言中具有递减运算符的习语.当然,有时语言中有不同的,更好的方法,但我认为JS没有任何特殊的计数习语.
@GrandOpener"惯用语"是指"母语人士通常理解的表达".对于类C语言的用户来说,预定义是非常容易理解的,并且通过扩展,"!( - x)"也是如此.是否_using_ something是一个好主意®是一个单独的问题,完全取决于它是如何惯用的.(例如,我非常怀疑你会遇到许多语言的程序员,他们不理解"goto"的作用,尽管经常表达的意见是在你的代码中包含它在名单上的"Lust"和"Murder"之间八个致命的罪中.)
@Pharap那是因为C#和Java没有隐含地将`int`转换为`bool`,并且与`! - `的使用完全无关.
@jmbpiano不,对不起,但那不是那个词的意思.惯用语对于母语使用者来说是**自然**,或者是语言的**特征**.自然语言的例子:许多移民说英语破碎的东西通常是可以理解的,但显然不是惯用的英语.编程示例:在Rust函数结束时使用`return`显然是可以理解的,但在文档中特别称为不是惯用的Rust.
@GrandOpener足够公平.即便如此,这更多是辩证分歧的情况,而不是类似于使用"破碎"语言的非母语人士.我会把它比作"血腥"的贬义.(例如"血腥的地狱","血腥的git")这个词在起源和主要用途中是英国英语成语.但是,如果不经常,北美英语使用者仍然可以很好地理解和使用它.从这个意义上讲,它通常是一种英语成语.Simarly`!( - x)`通常是**一种类似C语言的习语,_may_在_specific_ C-like方言JavaScript中使用频率较低.

4> Lucas..:

这是一个速记.

! 不是".

-- 递减一个值.

因此,!--检查从否定递减值的结果获得的值是否为假.

试试这个:

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

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

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


是.(尝试`var x = 2; console.log(!x--); console.log(!x--); console.log(!x - );`).虽然后修复` - `可能先执行,但其返回值是递减前的变量值([Decrement Opperator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/)参考/运营/ Arithmetic_Operators#递减)).

5> Sterling Arc..:

!是JavaScript NOT运算符

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

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


WTH是一个"虚假陈述"?
@Bergi我假设你真的知道这意味着什么,但万一你没有(或其他任何人没有)[这里是JavaScript的解释](http://james.padolsey.com/javascript/truthy-falsey /)这个概念(如Python)也可以很好地翻译成其他语言.
@Dannnno:我知道* falsy *的值是什么,*声明*是什么,所以我知道在JS中没有像“ falsy语句”这样的东西。我认为这并不涉及[逻辑术语](https://en.wikipedia.org/wiki/False_statement)。

6> james turner..:
if(!--pending)

手段

if(0 == --pending)

手段

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


而**是编写代码的明确方法.当然,我更喜欢`if(0 == pending)`,因为有可能出现错别字.`if(0 = pending)`是语法错误.`if(pending = 0)`是一个在完成的代码中会导致令人困惑的行为的赋值.
@TheoBrinkman:实际上`if(0 = pending)`不是语法错误 - 它解析得很好 - 但是参考错误因为`0`不可分配(ref ECMA-262(第6版)sec 12.14.1).

7> Brendan Abel..:

它是非操作符,后跟就地预先递减器.

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

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



8> MinusFour..:

它只减少pending一个并获得其逻辑补充(否定).任何不同于0的数字的逻辑补码是false0,它是0 true.



9> Ben Aubin..:
说明

这是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


10> Michael Gear..:

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

我不知道为什么人们会在他们的头脑中得到它,你不能在!操作员之后使用空间.我认为它来自机械空白规则的严格应用,而不是常识.几乎我看到的所有编码标准都禁止所有一元运算符之后的空格,但为什么呢?

如果有一种情况你明显需要这个空间,那就是一个.

考虑一下这段代码:

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

不仅是!--捣碎在一起,你(也会抨击它们.难怪很难说出与什么相关的东西.

更多的空格使代码更加清晰:

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

当然,如果你习惯于机械规则,比如"没有空间内的空间"和"一元经营者之后没有空间",这可能看起来有点异国情调.

但是看一下额外的空格如何组合并分离if语句和表达式的各个部分:你已经得到了--pending,所以--它显然是它自己的运算符并且紧密相连pending.(它递减pending并返回递减的结果.)然后你已经将!它与之分开,所以它显然是一个独特的运算符,否定了结果.最后,你已经得到if()围绕整个表达式,使其成为一个if陈述.

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

这里的空白用于传达意义,而不是遵循一些机械编码标准.

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有