位运算在组件封装时参数传递的运用

引言

在实际开发当中,我们经常会需要处理组件的封装以及相应的参数传递,如何能用更少更简单的入参调用实现所需的场景,这对于组件封装者来说的确是需要考虑的一件事。

举这样一个例子,笔者封装了一个资讯列表的Tab页,提供各个板块的资讯信息,现在需要把这样一个组件对外暴露,要求能够通过更少的参数配置帮助调用方实现所需板块的资讯列表展示。

一些尝试

如果封装组件的 Tab 比较少的情况下,我们可以通过布尔值的配置来实现相应内容的展示,例如:

jsx 复制代码
return <Information
    isShowIntroduction={true} // 配置推荐
    isShowFollow={true} // 配置关注
    isShowHot={true} // 配置热榜
></Infomation>

但如果 Tab 有 10 个甚至更多,一个个传布尔值参数就不是一个好的做法了。

当然我们也可以传入一个 tabCode 的数组,例如:

jsx 复制代码
return <Information
    tabs={[0, 2, 3, 5, 8]}
></Infomation>

这样也不是不行,只不过传入引用类型的参数背后可能还是会需要一系列的逻辑来将其处理成简单的基础类型来进行比对,那我们就想,能否通过传入一个有特点的参数来区分不同的板块组合?当然是可以的,不卖关子,直接来说一说我们的主角------位运算

JavaScript 位运算

运算符 名称 描述
& AND 如果两位都是 1 则设置每位为 1
| OR 如果两位之一为 1 则设置每位为 1
^ XOR 如果两位只有一位为 1 则设置每位为 1
~ NOT 反转所有位
<< 零填充左位移 通过从右推入零向左位移,并使最左边的位脱落。
>> 有符号右位移 通过从左推入最左位的拷贝来向右位移,并使最右边的位脱落。
>>> 零填充右位移 通过从左推入零来向右位移,并使最右边的位脱落。

我们这里只会用到 &<<

操作 结果 等同于 结果
5 & 1 1 0101 & 0001 0001
5 << 1 10 0101 << 1 1010
ini 复制代码
        0 1 0 1  =  5
    &   0 0 0 1  =  1
    ------------
        0 0 0 1  =  1

可以看到 & 运算,两个二进制数只有末位数都全是 1 ,其它位都有 0 存在,所以他的结果是 1,而 << 运算,0101 左移之后末尾补 0 变成了 1010,也就是 10。

位运算处理法

利用这个特性,我们可以做如下操作:

js 复制代码
// 假设我们封装的组件提供以下 tab 名称的板块内容,并按顺序排列
const tabArr = ["推荐", "关注", "热榜", "亚运会", "发现", "当地", "听书", "小视频", "小说"];
  1. 获取需要展示的板块的下标,并左移下标数,将所有结果做累加
  2. 左移的目的是保证从右数 n + 1 项为 1, 后续利用二进制 & 运算每一位只有都是 1 才真正是 1 的特性做比对,即找到 n + 1 项为 1 的那个下标对应的板块
js 复制代码
// 假设我们需要展示:["推荐", "关注", "热榜", "当地", "小说"],对应的下标分别是:[0, 1, 2, 5, 8]
const tabsTotalIndex = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 5) + (1 << 8); // 295

也就是说,调用方只需要根据封装组件提供的 tabArr 说明,传入 tabs = 295 即可,也就是:

jsx 复制代码
//  ["√推荐", "√关注", "√热榜", "亚运会", "发现", "√当地", "听书", "小视频", "√小说"]
const tabsTotalIndex = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 5) + (1 << 8);

return <Information tabs={tabsTotalIndex} />

此时封装的组件需要根据传入的 tabs 做如下处理:

js 复制代码
// tabs = 295;
const tabArr = ["推荐", "关注", "热榜", "亚运会", "发现", "当地", "听书", "小视频", "小说"];
const newTabArr = tabArr.filter((_, key) => {
    const num = 1 << key;
    return (tabs & num) === num;
}); // ["推荐", "关注", "热榜", "当地", "小说"]

最终,我们得到调用方实际需要的板块 newTabArr 进行展示。

当然,这个例子中的 tabArr 只是为了便于说明,实际项目中肯定不会是这么简单的字符串数组,不过相信从这个例子中能够体会到位运算带来的便利,其实它还有很多的妙用,以及一系列的骚操作,这里就不做延展了,有兴趣的自己去发现喽!

相关推荐
万物得其道者成13 分钟前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
小白小白从不日白14 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风26 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom38 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan41 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
^^为欢几何^^1 小时前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang1 小时前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
北岛寒沫6 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
everyStudy6 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript