本文深入解析JavaScript中按位非(~)和双按位非(~~)运算符的底层实现机制。~运算符将数值转换为32位整数并取反,常用于判断字符串中是否包含某子串;~~运算符则通过两次取反实现类似Math.floor的向下取整效果。文章提供了具体的模拟实现代码,帮助开发者理解其处理浮点数、NaN及非数字类型的行为。
~运算符的转换逻辑与模拟实现
对于typeof结果不为“number”的类型,执行此类运算时会尝试将其转换为32位整数;若转换失败,则结果为NaN。
JavaScript在位运算方面采用了更为简化的实现方式,其底层原理可大致理解为以下逻辑:
具体实现代码如下:
var testData=-2.9;
var testResult=(typeof testData==="number"&&!isNaN(testData)&&testData!==Infinity)?(testData>0)?-Math.floor(testData)-1:-Math.ceil(testData)-1:-1; ~运算符对非数字及特殊值的处理
当数据尝试转换为32位整数后结果小于0时,需进行向上舍入处理,例如-2.9转换为-2;若结果大于0,则进行向下舍入,例如2.6转换为2。
若数据无法转换为32位二进制表示,则结果为NaN,进而转换为-1;例如~{}或~NaN的结果均为-1。
同理,~function(){return 100;}的结果也为-1。
~运算符在jQuery中的实际应用
在jQuery库中,常见用法如if(!~this.className.indexOf(str)){ //执行某些操作};此处this.className.indexOf(str)的返回值要么大于-1,要么等于-1。当等于-1时,~-1的结果为0,因此!~-1为true,从而判断this不包含str对应的class名。
~~运算符的原理与模拟实现
对于~~运算符,其原理相同,也可表示为:
具体实现代码如下:
var testData=2.1;
var testResult=(typeof testData==="number"&&!isNaN(testData)&&testData!==Infinity)?(testData>0)?Math.floor(testData):Math.ceil(testData):0; 同样采用向上或向下舍入的方式来理解其行为。