首先这个~在很多编程语言里都有,不止限于js
Javascript 按位取反运算符 (~) ,对一个表达式执行位非(求非)运算。如 ~1 = -2; ~2 = -3;~-1=0
这个符号很少见,前端js写了那么久,竟然还是第一次遇到。既然遇到了,就不能直接略过。
~1=-2是如何实现的呢,下面我们来看看计算过程:
一、输入为正数(1和2)
(1)二进制原码:0000 0001,0000 0010
(2)按位取反:1111 1110,1111 1101
(3)转成原码二进制,由于第一位是1,因此为负数,负数转成原码,第1位符号位不变,其余取反+1:1000 0010,1000 0011
(4)原码二进制转成十进制则为 -2,-3
因此 ~1=-2,~2=-3。
二、输入为负数(-1,-2)
(1)二进制原码:1000 0001,1000 0010
(2)1开头为负数,保持第1位符号位不变,取反+1,得到补码:1111 1111,1111 1110
(3)取反得到结果0000 0000,0000 0001
(4)转成十进制则为0,1
经过以上的取反过程推算,对原码、反码、补码等概念又重温了一遍。

如果使用两次~~

就是执行两次按位取反,其实就是保持原值,但是注意虽然是原值,但是对布尔型变量执行这个操作,会转化成相应的数值型变量,也就是 ~~true === 1,false === 0。
你的例子里就是利用了这个特性,keystr方法要求返回值是数值型,但是a[key] < b[key]得到的结果是true或false,布尔型,所以用~~处理一下,这种方法速度快,代价远小于写表达式或者判断条件。
对于布尔型可以快速的将其转化成对应的整型