~运算符的使用

873 阅读2分钟

~运算符先将值强制类型转换成32位数字,然后执行字位操作“非”,~X大致等同于-(x - 1)。 ~有以下用法:

一、与 indexOf() 方法共用

-(x - 1)中唯一能够得到0的(严格来说是-0)的x值是-1,也就是说如果x为-1时,~和一些数字值在一起时会返回假值0,其他情况会返回真值。

-1是一个“哨位值”,哨位值是那些在各个类型中(这里是数字)被赋予了特殊的含义的值。比如,在C语言中,我们用-1代表函数执行失败,用大于等于0的值来代表函数执行成功。

JavaScript的字符串 indexOf() 方法也遵守这一惯例。该方法在字符串中搜索指定的子字符串,如果能找到就返回子字符串所在的位置(从0开始),否则返回-1。

indexOf() 方法不仅能得到子字符串的位置,还能用来判断字符串中是否包含指定的子字符串,相当于一个条件判断,例如:

var a = 'hello world';

if (a.indexOf('lo') >= 0) {
  // true
}

if (a.indexOf('lo') != -1) {
  // true
}

if (a.indexOf('ol') < 0) {
  // true
}

if (a.indexOf('ol') == -1) {
  // true
}

>= 0== -1这样的写法不是很好,称为“抽象渗漏”,意思就是在代码中暴露了底层的实现细节,这里指的是用 -1 作为失败的返回值,这些细节应该屏蔽掉。 ~和 indexOf() 一起可以将结果强制类型转换(实际上仅仅是转换)为真/假值:

var a = 'hello world';

~a.indexOf('lo'); // -4 true
if (~a.indexOf('lo')) {
  // true
}

~a.indexOf('ol'); // 0 false
!~a.indexOf('ol'); // true
if (!~a.indexOf('lo')) {
  // true
}

如果用 indexOf() 返回-1,~将其转换成假值0,其他情况一律转换成真值。

二、字位截取

~~中的第一个~执行ToInt32并反转字位,然后第二个~再进行一次字位反转,即将所有的字位反转回原值,最后得到的仍然是ToInt32的结果。

很多人使用~~来截取数字值的小数部分,如:

image.png

但值得注意的是,负数是不可以使用的:

image.png

但我发现:

image.png

于是我得到了一个结论,~~x,x为正数时,~~x相当于Math.floor(x),x为负数时,~~x相当于Math.ceil(x)

不过截取小数点的方法,使用x | 0似乎更好。