记录--对于$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 ...
随机推荐
- gateway 是什么?
Gateway 定义是什么? 百度百科解释: 网关(Gateway)又称网间连接器.协议转换器.网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连. 网关既可以用于广 ...
- CF1849
传送门 A 氵 B 在吃了五次罚时后,我终于放弃了卡常优先队列,并发现:把余 \(0\) 看作余 \(k\),答案就是余数从大到小排列的,每种余数内部又按照下标排序. C 我为什么没想到哈希?自我检讨 ...
- typescript 实现enum枚举值定义为对象
壹 ❀ 引 最近因为有一些闲散时间,所以一直在做将Class组件重构为typescript + hooks组件的工作,结果今天就遇到一个有趣的问题.我们知道react Class组件一般都会定义Com ...
- SATA学习笔记——名词解释
SATASATA(Serial Advanced Technology Attachment,串行高级技术附件)是一种基于行业标准的串行硬件驱动器接口,是由Intel.IBM.Dell.APT.Max ...
- 【leetcode】如何实现 regex 正则表达式引擎
题目 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字 ...
- Jsp+Servlet实现文件上传下载(四)--下载文件
接着上一篇讲: Jsp+Servlet实现文件上传下载(三)--删除上传文件 点击打开链接 本章来实现一下下载文件功能,同时优化了一下上一章中的代码. 废话少说,上代码 ------------ ...
- Redis服务端事件处理流程分析
一.事件处理 1.1 什么是事件 Redis 为什么运行得比较快? 原因之一就是它的服务端处理程序用了事件驱动的处理方式. 那什么叫事件处理?就是把处理程序当成一个一个的事件处理.比如我前面文章:服务 ...
- 【Azure API 管理】APIM如何配置客户端证书的CRL检测策略
证书吊销列表 (Certificate Revocation List ,简称: CRL) 是 PKI 系统中的一个结构化数据文件,该文件包含了证书颁发机构 (CA) 已经吊销的证书的序列号及其吊销 ...
- Nebula Importer 数据导入实践
本文首发于 Nebula Graph Community 公众号 前言 Nebula 目前作为较为成熟的产品,已经有着很丰富的生态.数据导入的维度而言就已经提供了多种选择.有大而全的Nebula Ex ...
- 在.Net中使用Java代码?
前言 你没有看错,我确实在.Net6的项目中在编写java,我都using java了,算不算在写java那? using com.microsoft.sqlserver.jdbc; using ja ...