什么!!〜做什么?

Alf*_*red 25 javascript

我正在阅读这篇博文,上面提到了:

!!~ 
Run Code Online (Sandbox Code Playgroud)

我不知道这是做什么的?起初我以为它会给出错误,但下面的代码确实运行:

var _sessions = [
    "_SID_1",
    "_SID_2",
    "_SID_3",
    "_SID_4"
];

if(!!~_sessions.indexOf("_SID_5")) {
    console.log('found');
} else {
    console.log('!found');
}
Run Code Online (Sandbox Code Playgroud)

输出:

node test.js 
!found
Run Code Online (Sandbox Code Playgroud)

Jam*_*ice 28

~是按位非运算符.它反转其操作数的位.!是逻辑非运算符.按位运算符将0在应用时返回-1,这是indexOf在数组中找不到值时返回的值.从0评估到false,双重否定它将简单地返回false(布尔值,而不是数字值):

var index = _sessions.indexOf("_SID_5");
console.log(~index); // 0
console.log(!~index); // true
console.log(!!~index); //false
Run Code Online (Sandbox Code Playgroud)

对于返回的任何其他可能值,按位非运算符将返回小于0的值indexOf.由于任何其他值将被评估true,它只是一个简写方法(它的两个字符数相同!)检查元素是否存在于数组中,而不是显式比较-1:

if (_sessions.indexOf("_SID_5") > -1) {
    // This would work the same way
}
Run Code Online (Sandbox Code Playgroud)

更新

关于这一点的表现,它(至少在Chrome中)比较常见的比较-1(它本身略微慢于比较0)略微慢一些.

这是一个测试用例,结果如下:

在此输入图像描述

更新2

事实上,您的问题中的代码可能会缩短,这可能是作者试图做的.您可以简单地删除!!,因为~将始终导致0或低于(并且0是唯一要评估的值false):

if (~_sessions.indexOf("_SID_5")) {
    // This works too
}
Run Code Online (Sandbox Code Playgroud)

但是,在稍微不同的情况下,添加!运算符是有意义的.如果要将变量运算符的结果存储在变量中,则它将是一个数值.通过应用逻辑非运算符,您将获得一个布尔值(并再次应用它可确保您获得正确的布尔值).如果由于某种原因你需要一个布尔值而不是数字布尔值,它会更有意义(但你仍然可以使用-1或与正常比较0):

var inArray = !!~_sessions.indexOf("_SID_5");
console.log(typeof inArray); // boolean
Run Code Online (Sandbox Code Playgroud)


jgr*_*nen 7

唐纳德克努特:"[...]过早的优化是所有邪恶的根源"

为了便于阅读:请使用

.indexOf !== -1
Run Code Online (Sandbox Code Playgroud)


ppe*_*rka 5

这很好地解释了:

Javascript中的波形符运算符

将两个NOT运算符混合在一起可以产生一些有趣的结果:

!〜( - 2)= false

!〜( - 1)=真

!〜(0)= false

!〜(1)= false

!〜(2)= false

所以这只是检查值是否等于-1,如果找不到匹配,则indexOf返回-1