JavaScript中的"双波浪"(~~)运算符是什么?

jis*_*smo 518 javascript

我在一些代码中看到了这一点,我不知道它的作用:

var jdn = function(y, m, d) {
  var tmp = (m <= 2 ? -1 : 0);
  return ~~((1461 * (y + 4800 + tmp)) / 4) + 
         ~~((367 * (m - 2 - 12 * tmp)) / 12) - 
         ~~((3 * ((y + 4900 + tmp) / 100)) / 4) + 
         d - 2483620;
};
Run Code Online (Sandbox Code Playgroud)

什么是~~运营商吗?

gho*_*ppe 662

~~是一个双非按位运算符.

它被用作更快的替代品Math.floor().

  • @ghoppe:值得注意的是它与`.floor()`的不同之处在于它实际上只删除了小数点右边的任何内容.当使用负数时,这会产生差异.此外,它将始终返回一个数字,永远不会给你"NaN".如果无法将其转换为数字,则会得到"0". (286认同)
  • 我使用这种非常大的数字(在base-62编码期间将Navigation Timing API中的数字除以62的结果)遇到了整数溢出问题.例如,在Firefox,Chrome和IE中,~~(2419354838.709677)== -1875612458,而Math.floor(2419354838.709677)== 2419354838. (23认同)
  • @ghoppe:是的,这两个不操作实际上比单层方法更快.当我在计算机上的Firefox中测试时,它们运行大约0.2微秒而不是0.5微秒.这意味着你需要在它显而易见之前使用它.在像OP中那样的功能中,它只是微优化,只会使代码更难以遵循. (16认同)
  • 不要用~~!在IE10中,它比同样的其他按位操作慢8倍!更好地使用零右移(>> 0),它是最快的,并且看起来更类似于有符号到无符号的转换(>>> 0). (7认同)
  • ~~ 是 Math.floor() 的更快别名,-~ 是 Math.ceil() 的别名 (4认同)
  • 与Math.trunc()类似,但与Math.floor()不同 (3认同)
  • @Guffa测试页面可编辑是件好事.:)我刚刚测试了它,`~~`的速度是Safari 5上的`Math.floor`的两倍. (2认同)
  • @Guffa屏幕更新率与计算速度有什么关系?有人可能在内部使用循环或鼠标事件. (2认同)

Guf*_*ffa 164

它隐藏了代码的意图.

它是两个单个波形符号运算符,因此它按位补码(按位不是)两次.操作相互取出,因此唯一剩下的效果是在应用第一个操作符之前完成的转换,即将值转换为整数.

有些人使用它作为更快的替代品Math.floor,但速度差异并不那么显着,在大多数情况下,它只是微观优化.除非你有一段真正需要优化的代码,否则你应该使用代码来描述它所做的事情而不是使用非操作副作用的代码.

更新2011-08:

通过在浏览器中优化JavaScript引擎,运算符和函数的性能会发生变化.使用当前的浏览器,在某些浏览器中使用~~而不是Math.floor更快,而在某些浏览器中则不会更快.如果您真的需要额外的性能,则需要为每个浏览器编写不同的优化代码.

见:波浪与地板

  • 为"它隐藏了代码的意图"+1,我浪费了10分钟来知道`~~`的作用.无论如何,我也不得不承认它已经强大了我的黑暗面已经诱惑我在我的新代码中永远使用`~~`代替`Math.floor`.:)))) (92认同)
  • 请记住,Math.floor()存在是有原因的.不要使用~~因为它比Math.floor快2微秒,如果你不明白它可能导致溢出或其他意外结果的位置. (4认同)
  • 请注意像JSPerf这样的微测试(必要)运行测试代码的次数足以实现运行时优化(例如在V8中).该测试表明(如果使用得非常多)`Math.floor()`_can_和Chrome上的"~~"一样快,但并不是它始终具有相同的速度.现在,很难确定一位代码是否比另一位代码"更快"(考虑到不同的浏览器和调用方案). (2认同)

bow*_*ior 120

~(5.5)   // => -6
~(-6)    // => 5
~~5.5    // => 5  (same as Math.floor(5.5))
~~(-5.5) // => -5 (NOT the same as Math.floor(-5.5), which would give -6 )
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅:

  • `〜(-5.5)`=>`4`,`〜(4)`=>`-5`,`~~(-5.5)`=>`-5`.因此,与`Math.floor`不同 (10认同)

Jas*_*use 20

差异非常简单:

长版

如果您想要更好的可读性,请使用Math.floor.但是如果你想最小化它,请使用代字号~~.

互联网上有很多消息来源说Math.floor更快,但有时候~~.我不建议您考虑速度,因为在运行代码时不会注意到它.也许在测试等,但没有人可以看到这里的差异.更快的是使用~~更快的加载时间.

精简版

~~更短/占用更少的空间.Math.floor提高了可读性.有时代字号更快,有时Math.floor更快,但不明显.

  • Math.trunc(),而不是Math.floor() (7认同)
  • 对.它主要是一种风格选择,比如布尔(foo),(foo?true:false)之间的选择,或者当你想将变量强制转换为布尔值时选择!! foo. (4认同)