记录--对于$off,Exclude 和 Extract的一点理解
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

一.typescript 高阶类型 Exclude 和 Extract
Exclude<T, U>
TypeScript 2.8 中增加了 Exclude 类型,该如何理解这个高级类型的定义呢?
type Exclude<T, U> = T extends U ? never : T;
从 Exclude 的定义来看,就是判断 T 是否继承于 U,如果是,则返回 never,否则返回 T。
1. T, U 之间的关系,是否是基于结构相似呢?
interface IPerson {
name: string,
age: number,
sex: 0 | 1,
}
interface IMan {
name: string,
age: number,
}
type Man = Exclude<IPerson, IMan> // 等效于 type Man = never
结论:只需要两者类型能够保持一致,同时 T 的类型能够兼容 U 的类型即可。
2. 对于联合类型,是如何进行类比的?
type Fruits = "apple" | "banana" | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Exclude<Fruits, DislikeFruits> // 等效于 type FloveFruits = "peach" | "orange" // 实际上 Exclude 进行的比较
type FloveFruits =
| ("apple" extends "apple" | "banana" ? never : "apple")
| ("banana" extends "apple" | "banana" ? never : "banana")
| ("peach" extends "apple" | "banana" ? never : "peach")
| ("orange" extends "apple" | "banana" ? never : "orange")
// 所以最后的结果
type FloveFruits = "peach" | "orange"
当入参是联合类型时,它会以分布式的形式去进行比较。
Extract<T, U>
Extract 的功能,与 Exclude 相反,它是 提取 T 中可以赋值给 U 的类型。
type Extract<T, U> = T extends U ? T : never
1. T, U 之间的关系,是否是基于结构相似呢?
interface IPerson {
name: string,
age: number,
sex: 0 | 1,
}
interface IMan {
name: string,
age: number,
}
type Man = Extract<IPerson, IMan> // 等效于 type Man = IPerson
与 Exclude 相同,均是保持相同的结构即可,只不过他们的取值逻辑相反。
2. 对于联合类型,是如何进行类比的?
type Fruits = "apple" | "banana" | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Extract<Fruits, DislikeFruits> // 等效于 type FloveFruits = "apple" | "banana"
原理与 Exclude 类似,仅仅是取值的逻辑不同而已。
二.vue事件方法之$off方法的实现原理
vue中事件方法一共就四个,挂载在vue实例上的$off移除事件中心里面某个事件的回调函数,通常会用到,那么$off的内部实现原理是什么呢?下面我们来详细说下$off:
vm.$off( [event, callback] )
参数:
{string | Array<string>} event (只在 2.2.2+ 支持数组)
{Function} [callback]
作用:
移除自定义事件监听器。
如果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
原理:
该方法用来移除事件中心里面某个事件的回调函数,根据所传入参数的不同,作出不同的处理。
Vue.prototype.$off = function (event, fn) {
const vm: Component = this
// all
if (!arguments.length) {
vm._events = Object.create(null)
return vm
}
// array of events
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
this.$off(event[i], fn)
}
return vm
}
// specific event
const cbs = vm._events[event]
if (!cbs) {
return vm
}
if (!fn) {
vm._events[event] = null
return vm
}
if (fn) {
// specific handler
let cb
let i = cbs.length
while (i--) {
cb = cbs[i]
if (cb === fn || cb.fn === fn) {
cbs.splice(i, 1)
break
}
}
}
return vm
}
该方法内部就是通过不断判断所传参数的情况进而进行不同的逻辑处理。
首先,判断如果没有传入任何参数(即arguments.length为0),这就是第一种情况:如果没有提供参数,则移除所有的事件监听器。我们知道,当前实例上的所有事件都存储在事件中心_events属性中,要想移除所有的事件,那么只需把_events属性重新置为空对象即可。
接着,判断如果传入的需要移除的事件名是一个数组,就表示需要一次性移除多个事件,那么我们只需同订阅多个事件一样,遍历该数组,然后将数组中的每一个事件都递归调用$off方法进行移除即可。
接着,获取到需要移除的事件名在事件中心中对应的回调函数cbs。
接着,判断如果cbs不存在,那表明在事件中心从来没有订阅过该事件,那就谈不上移除该事件,直接返回,退出程序即可。
接着,如果cbs存在,但是没有传入回调函数fn,这就是第二种情况:如果只提供了事件,则移除该事件所有的监听器。这个也不难,我们知道,在事件中心里面,一个事件名对应的回调函数是一个数组,要想移除所有的回调函数我们只需把它对应的数组设置为null即可。
接着,如果既传入了事件名,又传入了回调函数,cbs也存在,那这就是第三种情况:如果同时提供了事件与回调,则只移除这个回调的监听器。那么我们只需遍历所有回调函数数组cbs,如果cbs中某一项与fn相同,或者某一项的fn属性与fn相同,那么就将其从数组中删除即可。
就这么简单。
本文转载于:
https://blog.csdn.net/leelxp/article/details/107212699
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--对于$off,Exclude 和 Extract的一点理解的更多相关文章
- 对socket的一点理解笔记
需要学web service,但是在视频中讲解到了socket套接字编程.以前貌似课上老师有提过,只是没用到也感觉乏味.现在遇到,自己看了些博客和资料.记录一点理解,不知正确与否. 首先说这个名字,叫 ...
- iOS 的一点理解(一) 代理delegate
做了一年的iOS,想记录自己对知识点的一点理解. 第一篇,想记录一下iOS中delegate(委托,也有人称作代理)的理解吧. 故名思议,delegate就是代理的含义, 一件事情自己不方便做,然后交 ...
- mycat的schema.xml的个人的一点理解
官方文档里讲的详细的部分的我就不再赘述了,我只是谈谈我自己的理解 刚开始接触mycat,最重要的几个配置文件有server.xml,schema.xml,还有个rule.xml配置文件 具体都是干啥用 ...
- 三层架构的一点理解以及Dapper一对多查询
1.首先说一下自己对三层架构的一点理解 论坛里经常说会出现喜欢面相对象的写法,所以使用EF的,我个人觉得他俩没啥关系,先别反对,先听听我怎么说吧. 三层架构,基本都快说烂了,但今天还是说三层架构:UI ...
- gslb(global server load balance)技术的一点理解
gslb(global server load balance)技术的一点理解 前言 对于比较大的互联网公司来说,用户可能遍及海内外,此时,为了提升用户体验,公司一般会在离用户较近的地方建立机房,来服 ...
- opencv笔记5:频域和空域的一点理解
time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...
- 关于web开发的一点理解
对于web开发上的一点理解 1 宏观上的一点理解 网页从请求第地址 到获得页面的过程:从客户端(浏览器)通过地址 从soket把请求报文封装发往服务端 服务端通过解析报文并处理报文最后把处理的结果 ...
- angular.js的一点理解
对angular.js的一点理解 2015-01-14 13:18 by MrGeorgeZhao, 317 阅读, 4 评论, 收藏, 编辑 最近一直在学习angular.js.不得不说和jquer ...
- RxSwift 入坑好多天 - 终于有了一点理解
一.前言 江湖上都在说现在就要赶紧学 swift 了,即将是 swift 的天下了.在 api 变化不大的情况下,swift 作为一门新的语言,集众家之所长,普通编码确实比 oc 要好用的多了 老早就 ...
- rt-thread中动态内存分配之小内存管理模块方法的一点理解
@2019-01-18 [小记] rt-thread中动态内存分配之小内存管理模块方法的一点理解 > 内存初始化后的布局示意 lfree指向内存空闲区首地址 /** * @ingroup Sys ...
随机推荐
- JS Leetcode 70. 爬楼梯 题解分析,斐波那契数列与动态规划
本题来自LeetCode70. 爬楼梯,难度简单,属于一道动态规划的入门题,题目描述如下: 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬 ...
- JS 这一次彻底理解插入排序
壹 ❀ 引 在前两篇排序文章中,我们分别介绍了冒泡排序与选择排序,趁热打铁,我们接着聊插入排序.老实说,在分析排序过程中头脑很清楚,过后再尝试写出排序代码还有点坎坷...可能是我脑瓜子不太机灵的问题, ...
- NC16611 [NOIP2009]最优贸易
题目链接 题目 题目描述 C国有n个大城市和m条道路,每条道路连接这n个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这m条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向 ...
- col命令
col命令 在很多UNIX说明文件里,都有RLF控制字符,当我们把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col命令则能有效滤除这些控制字符. 语法 col [options] 参数 - ...
- Swoole从入门到入土(12)——HTTP服务器[Response]
继上一节了解完请求对象之后,这一节我们着重了解响应对象(Response).响应对象主要用于将数据发现到客户端.当 Response 对象销毁时,如果未调用 end 发送 HTTP 响应,底层会自动执 ...
- Vue+SpringBoot+ElementUI实战学生管理系统-5.用户管理模块
1.章节介绍 前一篇介绍了项目的API接口设计,这一篇编写用户管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.项目截图 列表操作 动态图 4 ...
- nmap top N端口获取
使用nmap 扫描时可能会扫描tcp top100 top1000 端口, 有时需要去配置文件提取,配置文件路径/usr/share/nmap/nmap-services, 具体根据实际安装情况调整: ...
- Centos8上安装python3.X
一.更新yum源 命令:yum update 二.更新依赖环境 命令:yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sq ...
- 【Azure 环境】Azure 流分析服务(Steam Analytics) 报出 OutputDataConversionError 错误引起延迟及超时
问题描述 Azure 流分析服务(Steam Analytics) 报出 OutputDataConversionError 错误引起延迟及超时. 查看详细错误: 问题解答 在错误消息中,有非常明确的 ...
- Jmeter中属性跟变量的区别?
Jmeter属性全局生效,变量局部生效,jmeter属性默认读取jmeter.properties中的属性配置,在jmeter运行过程中,通过函数${_setProperty(属性名,属性值)来定义 ...