我刚刚浏览了一个JQuery插件,并遇到了以下代码:
var doAnimate = $.support.transition && animate
我确实理解短路,但这是一个使用短路的变量声明??
在询问有人比我更有经验的时候,我得到了以下答复:
如果他们加载了转换库,请使用它,否则请使用animate。
我想返回的值不是真或假,因为我听说短路不会返回真或假。
因此,如果未定义$.support.transition
,动画会存储在doAnimate
中吗?
这是怎么回事?我真的很困惑这个变量声明及其工作原理。我确实理解条件下的短路。
答案 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
。
答案 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.transition
是false
)。只要您使用doAnimate
只是为了真实(如代码中的示例),代码就可以正常工作。仅当doAnimate
为truthy
且transition
为truthy
(意为animate
)时,'fade'
才会为this.$element.hasClass('fade')
。
但请注意这种优化。大多数程序员不使用在不同情况下具有不同类型的变量,并且会将此代码视为过于复杂。因此,在大多数情况下,您可能需要添加另一个变量来存储this.$element.hasClass('fade')
的结果,并在doAnimate
中使用该布尔值(而不是使用animate
字符串)。