《omit.js源码》阅读笔记
-
我正在参与掘金会员专属活动-源码共读第一期,点击参与
-
本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与
-
这是源码共读的第36期,链接:juejin.cn/post/711878…
源码目录总览
一眼看下来,这个项目的结构非常简单,但是有很多我之前没有了解过的东西
src和tests目录不必多说,用来保存项目的源码和测试用例。.eslint*文件是eslint相关的配置.fatherrc.js是保存father的配置文件,father是一个由umi团队开发的NPM包研发工具.gitignore是git的忽略目录的配置文件.travis.yml是travis的流程配置文件,travis是一个项目持续集成的工具index.d.ts是一个typescript的描述文件,里面定义了omit函数的类型index.js是整个项目的入口,负责对外导出omit函数LICENSE是开源项目的开源协议package*.json是项目的锁定版本依赖文件和依赖文件README.md是项目的说明文档
1.源代码
function omit(obj, fields) {
// 通过 Object.assign 创建一个对传入对象的浅层复制
const shallowCopy = Object.assign({}, obj);
// 遍历传入的需要删除的属性数组
for (let i = 0; i < fields.length; i += 1) {
// 找到第 i 个需要删除的属性名称
const key = fields[i];
// 删除复制对象上的对应属性
delete shallowCopy[key];
}
// 最终返回这个复制的对象,结束
return shallowCopy;
}
export default omit;
源代码非常的简短,也没有对一些异常情况做处理,如果传入的fields字段是不可遍历的,就会直接抛出错误;不过总体来说,在需要删除多个属性的场景下,确实比自己手动写delete obj[xxx]方便的多。
但是相比于我们在项目中直接使用delete方法会直接修改目标对象来说,omit会创建一个副本对象,并在副本对象上完成操作,这一定程度上也有点immutable的感觉,减少了出错的可能。
2.测试用例
这两个测试用例是用jasmine的语法写的,jasmine是一个行为驱动的单元测试框架。
在测试用例中描述了两个场景
- 是否创建了一个对象的浅层复制
- 是否正确删除了传入属性
然后写出这两个创建对应的业务代码和判断逻辑。在进行判断的时候,使用了assert这个模块。(平时没有接触到Node.js的开发,所以完全不了解这个模块
assert是 Node.js 中的一个内置模块,用于进行断言。如果表达式的结果不符合预期,就会抛出错误
3.类型定义
在index.d.ts中,定义了omit函数的类型,包括接收的两个参数的类型和函数返回值的类型。可以看到在这里是有对函数的第二个参数做类型限制的,只接收特定类型的数组。而且这个函数本身的定义也与Typescript中的Omit方法非常类似。
这里再简单介绍一些 Typescript中一些常见的方法:
// Omit 删除给定类型的一些属性,并基于剩余的属性创建一个新的类型
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
// Pick 从给定类型中选取一些属性,并基于选取的属性创建一个新的类型
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
// Partial 将当前类型的所有属性都变成可选的
type Partial<T> = { [P in keyof T]?: T[P]; };
// Required 将当前类型的所有属性都变成必选的
type Required<T> = { [P in keyof T]-?: T[P]; };