重温js ——位运算

简介: 位运算是在数字底层(即表示数字的 32 个数位)进行运算的。由于位运算是低级的运算操作,所以速度往往也是最快的(相对其它运算如加减乘除来说),并且借助位运算有时我们还能实现更简单的程序逻辑,缺点是很不直观,许多场合不能够使用。

js 位运算符


什么是位运算?


位运算是在数字底层(即表示数字的 32 个数位)进行运算的。由于位运算是低级的运算操作,所以速度往往也是最快的(相对其它运算如加减乘除来说),并且借助位运算有时我们还能实现更简单的程序逻辑,缺点是很不直观,许多场合不能够使用。


js位运算符总共分为两类:


逻辑位运算符:位与(&)、位或(|)、位异或(^)、非位(~)

移位运算符:左移(<<)、右移(>>)、全右移(>>>)


  • 逻辑运算符


1.位与(&): 真真为真(1),其余为假(0)


var a = 1;
var b = 2;
console.log(a & b) // 结果是:1 


计算的过程如下:首先会把a 和 b 的值都转成二进制的数据(这里转换的数据是32的二进制哦),然后进行运算


20210111141541442.png


注意: 位运算 与 可以用于 b 中是否包含 a ,这个包含是指的是二进制的数据是否包含交集,具体的表达式如下: (a & b) === a


20210111142250966.png


2.位或(|): 假假为假(0),其余为真(1)


var a = 1, b = 2;
console.log(a | b) // 结果是 3


计算过程如下:


20210111143600977.png


注意: 这个功能一般常用来取两个二进制数据的并集


3.位异或(^):相同为假(0),不同为真(1)


var a = 1, b = 3;
console.log(a ^ b) // 输出结果是 2


运算过程如下:


20210111150400369.png


注意: 异或运算一般可以用于做减法,通过更大的那个值来除去那个小的值,还剩多少


4.非位(~):真为假,假为真


var num = 1; // 二进制 00000000000000000000000000000001
var num1 = ~num; // 二进制 11111111111111111111111111111110
console.log(~num1 ) // 结果是-2


js存储的的负数一般要经过以下步骤,才可以进行存储。


1.将真码变成反码, 就是说把所有的 0 都变成1


2.把反码变成补码, 就是说在反码的基础上加1,然后这个表示的才是一个存储的数据,当拿来运算的时候,需要逆向转换, 先减1,返回在取反


我们知道,js中的数字默认是有符号的。有符号的32位二进制的最高位也就是第一位数字代表着正负,1代表负数,0代表整数。那到底11111111111111111111111111111110等于多少呢?最高位为1代表负数,负数的二进制转化为十进制:符号位不变,其他位取反加1。取反之后为10000000000000000000000000000001,加1之后为10000000000000000000000000000010,十进制为-2。


注意:这个运算符的妙用可以使用在 判断值是否为-1上,例如:const filters = ['aa', 'bb', 'c']; if (~filters.indexOf(a)) {} 而不是 if( filters.indexOf(a) != -1 ) or if( filters.indexOf(a) >= 0), 如果取一个数字的整数,可以直接使用~~数字


这里还有一个计算非运算的技巧:

取非运算的时候,先把数据前面加一个负号, 然后在减1


c82352a8e55f4880ac0c5926ba50f90f.png


  • 移位运算符


5.左移(<<):首位符号为不动,把32位二进制数字整体往左边移动指定位数,左边超出部分被舍去,右边补0


9二进制有符号左移5位
    9<<5
    0000000000000000 0000000000001001
    ------
    0000000000000000 0000000100100000


公式:1×2数字2


计算机内是这样位移计算的,实际应用计算我们可以通过公式:num * (2^n) ,即:9*Math.pow(2,5)


b9ce50f3bb2a46f384209d8014e1c26e.png


6.右移(>>):首位符号为不动,把32位二进制数字整体往右边移动指定位数,右边超出部分被舍去,左边补0,这可能会丢失数据。


3二进制有符号右移5位
    3>>1
    0000000000000000 0000000000000011
    ------
    0000000000000000 0000000000000001


公式:

                                  image.png


0a50a6e4cd6d4883974c53e13ec14685.png


7.无符号右移(>>>):符号为也跟着一起移动,这样,无符号右移会把负数的二进制当成整数的二进制码


案列


// 运用场景,想要实现一个权限控制


// 我们使用一个枚举,或者一个对象都行
enum Permission {
    Read = 1,   // 0001
    Write = 2,  // 0010
    Create = 4, // 0100
    Delete = 8  // 1000
}
// 使用一个权限组, 需要哪个权限就使用 位或 运算符进行
//使用或运算
//0001
//或
//0010
//0011
let p: Permission = Permission.Read | Permission.Write;
//2. 如何判断是否拥有某个权限
//0011
//且
//0010
//0010
function hasPermission(target: Permission, per: Permission) {
    return (target & per) === per;
}
//判断变量p是否拥有可读权限
//3. 如何删除某个权限
//0011
//异或
//0010
//0001
p = p ^ Permission.Write;
console.log(hasPermission(p, Permission.Write));


相关文章
|
JavaScript
重温js——函数表达式和this
我们知道a 里面保存的是函数的引用地址,那么函数的调用是使用 () 来进行调用,保存到某个变量中的函数地址,直接 a() 就能调用该函数了。
重温js——函数表达式和this
|
Web App开发 移动开发 JavaScript
重温js—— 事件循环
大家都知道,js是单线程的语言。为啥要设置成单线程的呢? 不妨大家想一想,如果js是多线程的语言,一个线程来操作删除dom,一个线程来新增dom.那么这两个谁能先完成?结果就会变得不可控制。但是这里有的人肯定会说,html5提出了workers可以来启动多线程。没错,workers是可以用于启动多线程,在worker线程中你可以运行任何你喜欢的代码,不过有一些例外情况。比如:在worker内,不能直接操作DOM节点,也不能使用window对象的默认方法和属性,这也是存在一些弊端的(本质上也还是单线程)。
重温js—— 事件循环
|
JavaScript Java Go
重温js——作用域和作用域链
js代码执行,会在call stack创建对应的作用域(执行上下文),然后每一个上下文中会有一个VO来保存当前作用域的变量. 但是VO中如果会创建函数,那么函数中有一个额外的属[[scoped]]会指向栈中最顶层的VO(AO);
重温js——作用域和作用域链
|
JavaScript Go
重温js——执行上下文
在函数的那一张中,提到了全局环境和局部环境的概念,就是说在函数的执行过程中,函数内部的环境和外面是独立的,只是说函数内部可以使用外面全局环境的变量或者在调用全局函数的方法。在此,来总结一下js的执行环境。
重温js——执行上下文
|
JavaScript 前端开发
重温js——属性描述符
我们会发现,当我们去改变属性赋值的时候,会自动执行set函数,相当于是通知了set函数。属性取值的时候会自动的执行get函数,自动通知get函数。正是因为有这个自动通知的功能,vue2中的响应式系统就是基于Object.defineProperty()来实现对象的响应的。
重温js——属性描述符
|
JavaScript
重温js——原型和原型链
我们在前文说到,所有的对象都是通过new 函数来创建的,所有的函数也都是对象 . 那么问题来了,Function也是一个函数,那么他是怎么来的呢?(这个问题是不是类似有点像先有鸡和先有蛋的感觉)但是Function函数是在js引擎启动的时候,就直接把Function放入到内存中的.
重温js——原型和原型链
|
JavaScript
重温js—— 错误处理
上面的代码中,我们定义了一个变量,然后当中函数的方法来调用,最后输出一个结果。但是运行期间却报错了,并且下面的代码也是没有执行的,原因是代码报错了会阻止程序的运行。我们大家都知道js的解释性语言,代码解释一句然后执行一句,所以后面的代码是不能够直接执行的。
重温js—— 错误处理
|
JavaScript 前端开发
重温js——正则表达式
正则表达式是一种规则,在语法上各个语言都是一样的,有点是通用性很高,缺点是在平常开发中使用的频率并不是很高,主要使用的范围在用于判断字符串里面的规则。
重温js——正则表达式
|
JavaScript
重温js——构造函数基础
在上面的代码中,我们可以创建多个对象,使用函数的方式来创建的对象。(但是这两个对象是不一样的,每一次都创建一个新的对象)可以方便许多,除了上面的方法外,还有一种构造函数的方式来创建对象。
重温js——构造函数基础
|
JavaScript
重温js——函数基础
函数的作用,减少重复代码,实现代码的解耦。把某个功能点给抽离出来。使得代码阅读增加
重温js——函数基础