使用短路的变量声明

时间:2015-03-07 06:03:01

标签: javascript jquery

我刚刚浏览了一个JQuery插件,并遇到了以下代码:

var doAnimate = $.support.transition && animate

我确实理解短路,但这是一个使用短路的变量声明??

在询问有人比我更有经验的时候,我得到了以下答复:

  

如果他们加载了转换库,请使用它,否则请使用animate。

我想返回的值不是真或假,因为我听说短路不会返回真或假。

因此,如果未定义$.support.transition,动画会存储在doAnimate中吗?

这是怎么回事?我真的很困惑这个变量声明及其工作原理。我确实理解条件下的短路。

4 个答案:

答案 0 :(得分:4)

  

"如果他们加载了过渡库,请使用它,否则请使用动画。"

他们的意思是使用||运营商。

var doAnimate = $.support.transition || animate;

以上是做什么的,它检查$.support.transition是否可用,或加载,使用它,否则使用animate

当我们执行expr1 && expr2时,如果 falsey ,则返回expr1;否则,返回expr2

因此,当您执行var doAnimate = $.support.transition && animate;时,如果$.support.transition未加载或undefined,则doAnimate仍然保留{ {1}},而不是$.support.transition

如果已加载,则将使用animate。这与你想要的相反。这就是animate开始行动的地方。

当我们执行||时,如果 truthy ,则返回expr1 || expr2;否则,返回expr1

因此,当我们使用expr2并且加载了||时,将使用它,否则将使用$.support.transition

More on logical operators on MDN

答案 1 :(得分:0)

你可以告诉变量" doAnimate"确实用作布尔值,&&是他们写的意思。 " doAnimate"将是真是假。

&安培;&安培;是一个等价于AND的二进制逻辑运算符。如果您了解&&amp ;;的真相表你已经知道表达式中的两个元素都必须为true才能将整个表达式计算为true 短路利用了这个因素:如果第一个元素是假的,那么你不需要检查第二个元素。
在javascript中,true或false会被创造性地处理。在这种情况下,undefined被评估为false 您可以在MDN

了解更多信息

答案 2 :(得分:0)

在你的情况下:

var doAnimate = $.support.transition && animate;

仅当$.support.transition真实地评估animate并将animate分配给doAnimate

如果$.support.transition是假的。然后它将返回$.support.transition

的值

如果两个值均为真值,则仅需animate

但你真正想要的是:

var doAnimate = $.support.transition || animate;

它从左到右检查真实性。如果遇到任何第一个真值,它会将其存储到doAnimate。

答案 3 :(得分:0)

问题的代码是bootstrap的一部分。所以它经过了很好的测试,显然没有错。其他答案说代码应该是||而不是&&并不是真正理解代码在这种情况下的真实意图(Sphaso's answer是对的,但我会尝试更好地解释一下。)

如果我们检查Bootstrap sourcecode,我们会看到$.support.transition是一个布尔值。我复制到relevant portion of that bootstrap code下面,我们可以看到其余的代码,包括问题中的代码行:

var animate = this.$element.hasClass('fade') ? 'fade' : ''  // <--- animate is a string
// ... more code ...
  var doAnimate = $.support.transition && animate           // <--- doAnimate is either
                                                            //      a string or false
  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') // <- animate used
                                                                       //    as a string
  // ... more code ...
  if (doAnimate) this.$backdrop[0].offsetWidth  // <- doAnimate used only for truthfulness
  // ... more code ...
  doAnimate ?  // <---------------------------------- doAnimate used only for truthfulness
    this.$backdrop
      .one('bsTransitionEnd', callback)
      .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
    callback()

所以Bootstrap在这段代码中做了3个动作(这就是为什么他们需要2个变量,如果只需要2个动作,他们可能就不会以这种方式创建doAnimate变量而只是将整个内联内联): / p>

  • 1个操作正在使用animate变量,该变量具有用于css类的字符串(使用'fade'''设置)。但获取该变量集的条件并不简单(调用hasClass),因此在后面的代码中不再调用它,而是决定重用这个字符串变量,因为它是一个布尔值。

  • 另外两个动作取决于doAnimate变量,尽管它内部可能有不同的类型,但它们只是将它用作布尔值而没有严格的比较。

    doAnimate可能在里面:

    • 字符串:'fade'(被视为truthy)或空字符串''(被视为falsy)。
    • 或一个简单的布尔值(如果$.support.transitionfalse)。

    只要您使用doAnimate只是为了真实(如代码中的示例),代码就可以正常工作。仅当doAnimatetruthytransitiontruthy(意为animate)时,'fade'才会为this.$element.hasClass('fade')

但请注意这种优化。大多数程序员不使用在不同情况下具有不同类型的变量,并且会将此代码视为过于复杂。因此,在大多数情况下,您可能需要添加另一个变量来存储this.$element.hasClass('fade')的结果,并在doAnimate中使用该布尔值(而不是使用animate字符串)。