位运算实现权限组合
用位运算实现权限组合【渡一教育】_哔哩哔哩_bilibili
目标:使用一串二进制数字来表示当前用户的权限情况。
主要实现的技巧是使用一个某一位为1的二进制数字表示某个权限的开启,然后使用「与运算(&)」计算这个数字和表示全部权限状态的二进制数字,就可以得到该权限的开启情况。
同时还可以通过「按位或运算(|)」进行权限的开启,和「按位异或运算(^)」进行权限的切换。
ts
// 使用二进制数据进行权限控制
/** 是否可读 */
const canRead = 0b0001;
/** 是否可写 */
const canWrite = 0b0010;
/** 是否可执行 */
const canExecute = 0b0100;
/**
* 检查是否有某个权限
* @param permission 权限码
*/
function checkPermission(permission: number, permissionCode: number) {
// 只要对应位上不是1,则进行与运算,结果一定为0
return permission & permissionCode;
}
/** 切换某个权限 */
function togglePermission(permission: number, permissionCode: number): number {
// 按位异或运算,其中一个为1,另一个为0,结果为1,反之为0。
// 所以,不是该权限位的值都会保留原有的值,而该权限对应的位因为permissionCode上对应的位为1,所以会被切换。
return permission ^ permissionCode;
}
/** 开启或关闭某个权限 */
function setPermission(
permission: number,
permissionCode: number,
enable: boolean,
): number {
return enable ? permission | permissionCode : permission & ~permissionCode;
}
/** 只有可读权限 */
const readOnlyPermission = 0b0001;
/** 只有可读和可写权限 */
const readWritePermission = 0b0011;
/** 只有可读、可写和可执行权限 */
const readWriteExecutePermission = 0b0111;
console.log('readOnlyPermission', checkPermission(readOnlyPermission, canRead)); // true
console.log(checkPermission(readOnlyPermission, canWrite)); // false
console.log(checkPermission(readOnlyPermission, canExecute)); // false
console.log(setPermission(readOnlyPermission, canWrite, true).toString(2)); // 11
console.log(setPermission(readOnlyPermission, canExecute, true).toString(2)); // 101
console.log(setPermission(readOnlyPermission, canRead, false).toString(2)); // 0
console.log(checkPermission(readWritePermission, canRead)); // true
console.log(checkPermission(readWritePermission, canWrite)); // true
console.log(checkPermission(readWritePermission, canExecute)); // false
console.log(checkPermission(readWriteExecutePermission, canRead)); // true
console.log(checkPermission(readWriteExecutePermission, canWrite)); // true
console.log(checkPermission(readWriteExecutePermission, canExecute)); // true
手写bind函数
手写bind函数【渡一教育】_哔哩哔哩_bilibili
核心在于两点:
- 使用
apply
和call
方法实现返回的函数运行时会绑定新的上下文; - 使用
new.target
判断是否通过new
进行函数调用的,如果是,则返回通用通过new
调用的结果,否则返回函数执行的结果;
this指向
this 指向【渡一教育】_哔哩哔哩_bilibili
重点是this
是存在于执行上下文中的,也只有在函数执行时才会产生执行上下文,也才会产生this
。
数组去重方法实现
你不知道的数组去重【渡一教育】_哔哩哔哩_bilibili
核心思路:
- 逐个遍历数组元素的属性,查找剩余的数组元素中的有没有完全相同的。
- 两个值如果有一个是基本数据类型,直接使用
Object.is()
进行判断`; - 非基本数据类型,先判断内容长度;
- 具体每个属性的比对,遵循上面的逻辑;
使用预加载优化接口响应时间
说个你没见过的白屏优化方案 /dog_哔哩哔哩_bilibili
如果有个参数固定的get接口是必定会调用,且影响后续的页面加载或功能执行的。可以使用<a>
标签,设置ref
属性为prefetch
让这个接口提前调用,并且缓存返回值,这样在后续调用改接口时,浏览器就会使用之前的缓存的结果(如果之前的接口还没完成返回,那就会等待完成)。
但是需要注意,这个方法有以下缺点:
- 不支持get以外的请求;
- 不支持动态配置参数,token相关的参数最好通过cookie进行传递;
- 浏览器的缓存策略会受到响应头中相关字段的配置影响;
控制CSS animation的播放暂停
animation-play-state - CSS:层叠样式表 | MDN
使用animation-play-state
属性进行控制
CSS的层叠规则
层叠规则【渡一教育】_哔哩哔哩_bilibili
当同一个元素出现相同的CSS属性定义时,就会根据特定的规则进行比较,从而确定最终使用的CSS属性。比较的优先级为:
- 优先级:
- 作者样式表
!import
; - 默认样式表
!import
; - 作者样式表;
- 默认样式表;
- 作者样式表
- 特殊性
- 行内样式;
- id选择器;
- 类、伪类选择器;
- 元素选择器;
- 源次序 这里面作者样式表即自己编写的CSS样式,默认样式表即浏览器自带的样式。特殊性即常说的权重,其中的选择器可以通过重复出现来增加权重。源次序即样式代码出现的先后顺序(注意,标签内添加的class或id的先后次序不影响源次序)。