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

引言

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

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

相关推荐
半个落月29 分钟前
一个新手用 Bun + Axios 调通 DeepSeek API 的实践记录
javascript
不好听61330 分钟前
深入理解链表:线性数据结构的另一面
javascript·数据结构
林希_Rachel_傻希希34 分钟前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
小林ixn34 分钟前
从 Ajax 到异步编程:JSON 序列化、Event Loop 与 XHR 请求完全解析
javascript
丷丩2 小时前
MapLibre GL JS第47课:添加动画图标
javascript·gis·动画·mapbox·maplibre
快乐的哈士奇2 小时前
【Next.js实战①】Gmail API 按柜号检索邮件:OAuth 双 Cookie 与搜索 Fallback
开发语言·javascript·ecmascript
云水一下2 小时前
Vue.js从零到精通系列(五):全局状态管理——Pinia 核心与实践
前端·javascript·vue.js
kmblack13 小时前
javascript计算年龄
开发语言·javascript·ecmascript
Dick5073 小时前
ROS2 多机器人通用 Driver 层复盘:BaseRobotDriver 到多平台 Mock 切换实现
前端·javascript·机器人