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

引言

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

举这样一个例子,笔者封装了一个资讯列表的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 只是为了便于说明,实际项目中肯定不会是这么简单的字符串数组,不过相信从这个例子中能够体会到位运算带来的便利,其实它还有很多的妙用,以及一系列的骚操作,这里就不做延展了,有兴趣的自己去发现喽!

相关推荐
kite01211 小时前
浏览器工作原理06 [#]渲染流程(下):HTML、CSS和JavaScript是如何变成页面的
javascript·css·html
крон1 小时前
【Auto.js例程】华为备忘录导出到其他手机
开发语言·javascript·智能手机
coding随想4 小时前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
年老体衰按不动键盘4 小时前
快速部署和启动Vue3项目
java·javascript·vue
灵感__idea4 小时前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
星辰引路-Lefan4 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js
江城开朗的豌豆5 小时前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
江城开朗的豌豆5 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
TE-茶叶蛋5 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js
Carlos_sam7 小时前
Opnelayers:封装Popup
前端·javascript