Js位操作及其应用

更新日期: 2019-10-01阅读: 2.5k标签: 应用

我在看lodash实现一些工具函数的源码时发现lodash定义了一些bitMask的常量。我一开始没弄明这是什么鬼东西,用Google搜了一圈才发现是我之前接触过得位操作运算一类的东西。并且源码和我搜索的资料给我提供了另一种使用场景,感觉应用性还是蛮强的,所以干脆总结一下好了。

先以下面的表达式展开需要了解的基础知识。

// lodash 源码里定义的常量
var CLONE_DEEP_FLAG = 1

JavaScript遵循 IEEE 754 标准,无论是整数还是小数都是用双精度浮点数表述,双精度浮点数8个字节,表示64位二进制位,所以双精度浮点数的表示范围是-2^63 ~ 2^63-1。但是在进行位操作时则是用的32位数表示,也就是4个字节,表示范围为`-2^31 ~ 2^31-1,其中无论是32位还是64位,最高位都是符号位,0表示正数,1表示负数。

上面的表达式在进行位操作就会转换成下面这种,如果超过32位了,那超过的部分就会全部省去。

00000000 00000000 00000000 00000001

下面介绍几种常用的操作符。


&(位与)

let a = 1,
    b = 2
    
console.log(a & b) // 0

// 0001
// 0010
// = 0000

把变量a和变量b都展开成32位二进制数,省去前面的0,a的二进制表示为0001,b为0010,接着就是对应位数的二进制位比较,如果相同就是1,否则为0。


|(位或)

let a = 1,
    b = 2
    
console.log(a | b) // 3

// 0001
// 0010
// = 0011

参照上面一种,不同的是相同的二进制位上,只要有一个是1,则结果就是1,所以就是0011。


^(位异或)

这个和|有点区别,相同的地方在于如果同一位数上的数只要一个是1,则这个位数的结果就是1,不同的地方在于相同的位数上如果数值相同,则结果为0.

let a = 1,
    b = 2
    
console.log(a ^ b) // 3

// 0001
// 0010
// = 0011

let c = 3,
    d = 3
    
console.log(a ^ b) // 0

// 0011
// 0011
// = 0000


~(位异或)

这个和之前三个最大的区别是对单个数的操作,而不是两个数的比较结果。简单来说就是取反,对二进制上的每一位都取反。但是这里有个有趣的现象。

let a = 1;

console.log(~ a) // -2

无论用~取反任何数,得出的都是负数,而且是在正数上加一的负数。这里涉及三个概念:原码,反码,补码。首先明确一点,负数是以补码的形式存在的


原码

正数和负数的都是转换成二进制数后的样子,不同的是负数的原码在最高位+1。

// 4的原码
00000000 000000000 000000000 00000100
// -4的原码
10000000 000000000 000000000 00000100


反码

正数的反码和正数的原码一致。但负数的反码是对除了符号位上的其他二进制位取反。

// 4的反码
00000000 000000000 000000000 00000100
// -4的反码
11111111 11111111 11111111 11111011


补码

正数的补码还是和正数的原码一致,但负数的补码是在负数反码的基础上对最后一位加1。

// 4的补码
00000000 000000000 000000000 00000100
// -4的补码
11111111 11111111 11111111 11111100

所以说回上面提到的问题,3被~转换为-4的过程。

3:00000000 00000000 00000000 00000100
~3:11111111 11111111 11111111 11111011

// ~3 这时候表示的是负数,那就按照原码->补码的顺序倒推 
// 1.最低的位数-1
 11111111 11111111 11111111 11111010 
// 2.取反(除了符号位)
10000000 00000000 00000000 00000101
// 3.转换成十进制
-4


应用

介绍完了几种操作符,来说说有啥应用。

136. 只出现一次的数字

这是LeetCode上的一道题,题目是这样写的:

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

这个用上面介绍过的^(异或)操作符是最容易解答的,可以可以下^的特性。题目里说的是只有一个数是唯一的,其他都是两两出现,而相同的数字,就像我上面举例用了两个3,结果是0,因为每个二进制上的数都相同,所以结果就是每个位上都变成了0.

function onlyNums(arr){
    return arr.reduce((all,item) => all ^ item)
}

权限

这个例子就和我们的日常贴的比较近了。后台系统进行权限配置的时候,一般可能就是定义几个字符串定义不同的权限,如果一个人同时有很多权限,结果可能是个数组,也可能是把不同权限字符串拼接成新的字符串。

let permission1 = 001 // 登录权限
let permission2 = 002 // 创建权限
let permission3 = 003 // 删除权限
let adminPermission = '001,002,003'
// or
let adminPermission = [001,002,003]

如果换成位操作的思路:

let permission1 = 1 // 登录权限
let permission2 = 2 // 创建权限
let permission3 = 4 // 删除权限
let permission4 = 8 // 编辑权限

let adminPermission = (permission1 | permission2 | permission3)

这个时候检查adminPermission是否拥有某个权限就可以这样:

if((adminPermission & permission1) === permission1){
    // 有登录权限
}

删除某个权限:

adminPermission = adminPermission & (~ permission2)

新增某个权限:

adminPermission = adminPermission | permission4

除了上面两种场景,位操作


链接: https://fly63.com/article/detial/5697

使用html+css+js实现简易计算器

今天带大家做一个网页版的一个精美的计算器,使用的计算器可以实现标准计算器的功能,题目:计算器的实现,技术:html+css+js,使用html+css+js实现简易计算器,开启你的计算之旅吧。效果图如下,复制即可使用

C/S,B/S应用的区别

C/S(Client/Server) :客户端/服务器结构,其中客户端和服务器端都是独立的计算机;B/S(Browser/Server):浏览器/服务器结构,B/S是特殊的一种C/S结构,是对C/S的改进和变化,B/S是基于应用层http协议的web

浅谈单页应用和多页应用

多页面应用:每次页面跳转,后台都会返回一个新的HTML文档,就是多页面应用。单页应用:用vue写的项目是单页应用,刷新页面会请求一个HTML文件,切换页面的时候,并不会发起新的请求一个HTML文件,只是页面内容发生了变化

谈谈StorageEvent

我们在开发多Tab应用时候,常常会遇到多个Tab状态同步的问题。想象如下场景:用户主界面,显示用户购物车内待结算的商品总数。此时,用户可能打开多个Tab

flutter打开第三方应用的实现?

1.flutter开发者网站下载url_launcher插件;在 pubspec.yaml 文件中添加依赖;安装:flutter pub get;导入;_launchURL、_openMapApp为自定义方法名 可以根据自己的场景自定义名称

使用Flask构建一个Web应用

Flask是一个使用Python编写的轻量级Web应用框架。以管理员身份,打开命令提示符窗口,输入下面命令py -3 -m pip install flask

PWA渐进式Web应用:你需要知道的一切

你是否正处于选择 App 开发技术的两难境地?如今,渐进式 Web 应用程序需求旺盛。知道这是为什么吗 ?下面让我们来详细的梳理一下。移动电话用户的增长促使在线企业重新考虑对移动应用的优化

多数程序员难以简单的方式开发应用?

心理学中有一篇相当古老、但又非常重要的论文,题为《魔法数字七(上下浮动二):人类信息处理能力中的一些限制》。这篇文章衡量了大脑处理信息的极限,并给出了一个具体的数字:人脑可以同时容纳五到九个概念

使用typescript构建Vue应用

使用typescript构建Vue应用和使用js一样,都是通过vue-cli去初始化并创建一个vue项目,只不过使用typescript构建的时候要在脚手架问卷操作的时候勾选上typescript选项。使用typescript构建的Vue项目发生了一些变化:

BFC的作用及其应用

BFC就是块级格式化上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!