在《JavaScript高级程序设计 第三版》中,在 逻辑操作符 与 位操作符 章节感觉被没有讲解清楚。

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。在JS中只能当做 数值 进行位运算

1.按位与(AND)(位操作符)

按位与操作符由一个和号字符(&)表示,它有两个操作符数。从本质上讲,按位与操作就是将两个数值的每一位对齐,然后根据规则,对相同的位置上的两个数执行AND操作。

简而言之,按位与操作符只在两个数值的对应位都是1时才返回1,任何一位是0,结果都是0。

var result = 25 & 3
console.log(result) // 1
复制代码

25和3转化为32位的二进制码时,对应位上只有一位同时是1,而其它位的结果都是0,因此最终结果等于1.

2.按位或(OR)(位操作符)

按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。 简而言之,按位或操作在有一个位是1的情况下就返回1,而只有在两个位都是0的情况下返回0。 如果在前面按位与的例子中对25和3执行按位或操作。如下:

var result = 25 | 3
console.log(result) // 27
复制代码

这两个数值都包含4个1,因此可以把每个1直接放到结果中。二进制码 11011 等于十进制27。

JS中位运算符返回的是数值。JS中的位操作符只有1个功能:进行位运算

var number = 2
var logic = number < 5 | number > 0
console.log(number < 5) // true
console.log(logic) // 1 返回数值
复制代码
var logic = true | true
console.log(logic) // 1 可以看出 位操作符 只有1个功能:进行位运算。 
复制代码

测试1

var str1 = '9'
var str2 = '5'
console.log(str1 & str2) // 1
console.log(typeof (str1 & str2)) // 结果为 number 类型
复制代码

测试2

var number1 = 9
var number2 = 5
console.log(number1 & number2) // 1
复制代码

测试3

var obj1 = {
    valueOf: function() {
        return 9
    }
}
var obj2 = {
    valueOf: function() {
        return 5
    }
}
console.log(obj1 & obj2) // 1
复制代码

9的二进制:1001 5的二进制:0101 &操作结果:0001 = 1

我们可以发现,string类型、number类型、object类型操作结果相等,都会进行相应的数值转换。如果操作数不是数值类型,就会根据一定规则先把它转换成数值,若不能转化成数值则为NaN。

console.log(NaN & NaN) // 0
console.log('string' & 'string') // 字符串转化为NaN,结果为0
console.log(10 & NaN) // 10 & 0, 结果为0

console.log(Infinity & -Infinity) // 0
复制代码

3.强制转换类型(!!)

不论它的后面接的是什么数值,它的结果会被强制转换成bool类型

!!1 = true

!!0 = false

!!null = false

!!'' = false

!!'ccc' = true

!!{} = true
复制代码

总结:

(1) JS中只能当做数值(不是数值会先转换为数值)进行位运算,与 ^(按位异或)、~(按位非)、<<(左移)、>>(右移)、>>>(无符号右移)功能一样,若操作数为非数值,则转换为数值。

(2) 若操作number的类型的NaN、-Infinity、Infinity则会被转换为数值0.