这是什么类型的Javascript符号/快捷方式?

这是什么类型的Javascript符号/快捷方式?,javascript,Javascript,在某人的网站上遇到以下问题,我很想了解这里应用的快捷方式。为了演示,我简化了变量 function(){ _imaboolean || ($element.removeClass("hidden").addClass("visible"), this.imaboolean = !0) } 同样的事情 this._imaboolean && ($element.removeClass("visible").addClass("hidden"), this._ima

在某人的网站上遇到以下问题,我很想了解这里应用的快捷方式。为了演示,我简化了变量

 function(){
      _imaboolean || ($element.removeClass("hidden").addClass("visible"), this.imaboolean = !0)
 }
同样的事情

this._imaboolean && ($element.removeClass("visible").addClass("hidden"), this._imaboolean = !1)

这是一种短路评估,只有在第一部分出现故障的情况下,才会对第二部分进行评估。

我认为这是短路评估

 function(){
      if( ! _imaboolean){
         $element.removeClass("hidden").addClass("visible");
         this.imaboolean = true; 
     }
 }

在我看来,它通常也很糟糕,不应该被复制

此代码可以膨胀到:

function() {
    if (!this.imaboolean) {
        $element.removeClass("hidden").addClass("visible");
        this.imaboolean = true;
    }
}
|
用作短路,如果
imaboolean
true
则会中断,但如果
false
则会执行表达式的其余部分<代码>!0是表示
true
的简化方式(因为
0
在布尔表达式中的计算结果为
false

让我们来分析一下。首先我们看到
|
操作符,所以我们有
(语句)| |(另一个语句)
|
的工作方式是对第一条语句求值。如果计算结果为true,则会短路,并且不会计算第二条语句。第一条语句就是
\u
。如果这是一个真实的值(即,不是0或false或未定义的…),那么我们就到此为止,不转到第二个语句

第二种说法是

($element.removeClass("hidden").addClass("visible"), this.imaboolean = !0)
同样,有两个语句,用逗号分隔。逗号运算符计算这两个语句,并返回最后一个语句。因此它计算
$element.removeClass(“隐藏”).addClass(“可见”)
(它在$element上设置了一些类),然后计算
this.imaboolean=!0
(将this.imaboolean设置为真实值)。下次运行此函数时,它将由于
|
运算符而短路。

这是一些可怕的“聪明”代码,但是,让我们分解它吧

_imaboolean || ($element.removeClass("hidden").addClass("visible"), this.imaboolean = !0)
首先,让我们用占位符替换所有表达式(注意这些表达式不是纯表达式,并且有副作用):

请注意,
|
是短路,因此只有当
a
的计算结果为假y值时,才会计算正确的表达式-
(b,c)

因此,我们假设
a
计算为假y值,然后计算
(b,c)
。在这种情况下,
运算符分隔子表达式;所有子表达式都按顺序求值。表达式的结果是最后一个子表达式的结果

function(){
      _imaboolean || ($element.removeClass("hidden").addClass("visible"), this.imaboolean = !0)
 }
这意味着它大致相当于(尽管没有函数或绑定上下文,结果也会被抛出):

这有意义吗?不,当然不是

按照你的意思写:

if (!_imaboolean) {
  $element.removeClass("hidden").addClass("visible");
  this.imaboolean = true; // get rid of !0 too
}

太“聪明”了,太令人困惑了。不过,如果你把它读出来的话,间距是非常大的loud@user2246674尽管这个例子的可读性很差,但它还是相当地道的JS,因为问题的数量之多表明了这一点。@MattBall不幸的是(我不会说它很糟糕,它看起来很小。在这种情况下,源代码可能不是这样写的。@izuriel它看起来没有小化…这不是小化代码的样子。即使它没有小化,“可怕”也是一种延伸。“更难维护”,也许,但“可怕”?不。这不是
eval
。我所在的学校很难维护==很糟糕,但正如我所说,这是我的观点。@gbtimmon不确定它是从哪个网站上报废的,但它是从一个网站上撤下来的,并为演示目的进行了修改(如提问者所述)。除此之外,当使用更复杂的缩小过程(如闭包编译器)时,我经常看到这种情况。但我只是做了一个声明,以提供第二个参数来反对代码“糟糕”如果它被缩小了,它肯定不是。为什么
!0
1
将是一种更小型、更严格的true@gbitmmon因为
1
不是布尔表达式,因此当
!0
计算为
false
时,计算结果为
1
——一个布尔值。这就是为什么。@gbtimmon
!0!==1;1!==true;!0===true
-也就是说,1不是!0的直接替代品。上一条注释包含错误(它应该是“!0评估为true”)虽然truth-y/fale- y通常是按预期的方式工作的,但是有细微的差别——考虑jQueR.Engin,其中第一个参数可以是一个对象或一个布尔值。@ USE2246667我不买它。<代码> 1 就像truthy和<代码> 0代码>代码一样。然后看看会发生什么。
1
在那里被认为是正确的。而且(!0==1)并不重要。
|
操作符中有一个隐式转换为布尔值,所以您关心的是
toBoolean(!0)==toBoolean(1)
这总是正确的。@gbtimmon这就是为什么我使用
!=
==
来明确讨论细微差别。谢谢你。非常清晰的例子!!!
(function () { b; return c })()
if (!_imaboolean) {
  $element.removeClass("hidden").addClass("visible");
  this.imaboolean = true; // get rid of !0 too
}