对于$off,Exclude 和 Extract的一点理解
source link: https://www.fly63.com/article/detial/12178
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一.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
Recommend
-
6
Exclude parameter from Parameter Binding in WebAPI By Dan Nemec 23 Oct 2014 Lately I’ve been working on some WebAPI code with ActionFilters that inject parameters into the WebAPI action. For example, we authentic...
-
10
SEM A Google Ads setting allowed advertisers to exclude people of ‘unknown gender’ Employers, landlords and cr...
-
7
对于荒诞的一点感想by vincent2021年3月8日想法我个...
-
18
Conan 1.36 brings several significant enhancements, including several different enhancements to CMake integration, a new property strategy for cer...
-
12
Exclude lines in less (or journalctl)Skip to main content Exclude lines in less (or journalctl) Published: 23-05-20...
-
9
Exclude automatic properties from code coverage in Visual Studio 2015 advertisements I just upgraded a bunch of projects to VS2015/C#6.
-
5
对于教材写法的一点考虑 作者: physixfan 有感于Matrix67神牛的这篇文章(强烈建议大家去读一读),我也发表一下自己对于教材编写的一点看法。 1.对线...
-
9
Magento - SQL command to define & ldquo; Exclude & rdquo; On product images advertisements I'm wondering if there's some SQL command I...
-
5
对于当下银行转债的一点思考及讨论 经过上一轮真金白银的做低溢价策略,正好赶上了9,10月份那波回调。本韭菜终于知道自己...
-
2
V2EX › Apple 对于现有 2023 M2 系列一点建议
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK