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

引言

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

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

相关推荐
开开心心就好9 分钟前
Word图片格式调整与转换工具
java·javascript·spring·eclipse·pdf·word·excel
Stringzhua18 分钟前
JavaScript【5】DOM模型
开发语言·javascript·ecmascript
GanGuaGua37 分钟前
Vue3:脚手架
前端·javascript·css·vue.js·vue
weixin_431600441 小时前
使用 Vue Tour 封装一个统一的页面引导组件
javascript·vue.js·ecmascript
胡斌附体2 小时前
vue添加loading后修复页面渲染问题
前端·javascript·vue.js·渲染·v-if·异步加载
Dontla2 小时前
Webpack DefinePlugin插件介绍(允许在编译时创建JS全局常量,常量可以在源代码中直接使用)JS环境变量
运维·javascript·webpack
沐土Arvin3 小时前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
咖啡の猫4 小时前
JavaScript基础-创建对象的三种方式
开发语言·javascript·ecmascript
outstanding木槿4 小时前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
小吕学编程5 小时前
Jackson使用详解
java·javascript·数据库·json