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

引言

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

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

相关推荐
小高0071 分钟前
💥💥💥前端“隐藏神技”:15 个高效却鲜为人知的 Web API 大起底
前端·javascript
flyliu2 分钟前
再再次去搞懂事件循环
前端·javascript
XiaoMu_00118 分钟前
基于Node.js和Three.js的3D模型网页预览器
javascript·3d·node.js
卿·静23 分钟前
Node.js对接即梦AI实现“千军万马”视频
前端·javascript·人工智能·后端·node.js
Mintopia37 分钟前
🚀 Next.js 全栈 Web Vitals 监测与 Lighthouse 分析
前端·javascript·全栈
ITKEY_39 分钟前
flutter日期选择国际化支持
开发语言·javascript·flutter
Mintopia39 分钟前
🤖 AIGC + CMS:内容管理系统智能化的核心技术支撑
前端·javascript·aigc
子兮曰1 小时前
🚀95%的前端开发者都踩过坑:JavaScript循环全解析,从基础到高阶异步迭代
前端·javascript·性能优化
小桥风满袖1 小时前
极简三分钟ES6 - 数值的扩展
前端·javascript
用户47949283569151 小时前
面试官:讲讲css样式的优先级
前端·javascript·面试