JavaScript中!~操作符详解:按位取反与indexOf的巧妙结合
本文深入解析JavaScript中!~操作符的底层原理。通过剖析~按位取反运算与indexOf返回值的逻辑关系,揭示其用于判断元素是否存在于数组中的技巧。内容涵盖原码、反码、补码知识及具体数值计算示例,帮助开发者理解这一常见但易混淆的代码写法。
假期临近,工作节奏放缓,终于有了空闲时间。这段时间里,我沉浸在各类技术文章的学习中,这种状态让人感到充实且愉悦。
下午阅读一篇关于JavaScript的文章时,其中一段代码引起了我的注意,其写法有些特别。
JavaScript中!~操作符的代码示例
具体代码如下:
(function () {
var names = [];
return function (name) {
addName(name);
}
function addName(name) {
if (!~names.indexOf(name))//如果存在则不添加
names.push(name);
console.log(names);// ["linkFly"]
}
}())('linkFly');
!~操作符原理:按位取反与补码机制
代码中 `if (!~names.indexOf(name))` 这一行使用了 `!~` 操作符,其具体含义尚不明确。为了彻底理解,我们需要从 `~` 运算符入手进行分析。
通过实际测试可以发现,该运算结果遵循 `-(X+1)` 的规律。
查阅相关资料,部分文章仅简单解释为“按二进制位取反”,这往往让人难以直观理解其实际作用。
从字面意思来看,若用八位二进制表示数字3,即 `00000011`,对其按位取反得到 `~3 = 11111100`。然而,直接套用上述公式似乎对不上号。之前的解释过于抽象,实际上这涉及到计算机中原码、反码和补码的核心知识。
原码:最高位为符号位,0表示正数,1表示负数,其余位表示数值绝对值。反码:正数的反码与原码相同;负数的反码是原码符号位不变,其余位按位取反。补码:正数的补码与原码、反码相同;负数的补码是其原码符号位不变,其余位按位取反后末位加1。计算机内部通常以补码形式存储数值。特别地,8位二进制中 `(-128)D` 对应 `(1000,0000)B`,它没有对应的原码和反码。求补运算:不考虑符号位,对原码各位取反并在末位加1,得到的是该数相反数的补码。
结合文章中的例子,我们可以更清晰地理解这一机制。
`~` 表示按位取反,即将二进制位中的0变为1,1变为0。例如,若二进制为 `00111`,取反后变为 `11000`。
57的二进制表示为(1个字节):00111001 按位取反后(~57)的二进制: 11000110 此表示为十进制:-70 这是一个负数,是有符号的数,负数在计算机里要用其补码来表示:补码=符号位以后按位取反再加1. 所以-70(11000110)符号位以后按位取反后为(10111001) 再加1 则为(10111010) 换成十进制为:-58 因此~57=-58
至此,我们终于厘清了 `~` 运算的原理。虽然 `-(X+1)` 公式能快速得出结果,但理解其背后的二进制补码机制对于技术人员而言至关重要,这有助于深入掌握语言细节。
不禁感叹时间的流逝与知识积累的重要性。
基础是一切上层建筑的基石,潜心钻研技术之路虽漫长,但值得坚持。
以上就是本文的全部内容,希望读者能从中获得启发与收获。
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
