导读
本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
【若川视野 x 源码共读】第36期 | 可能是历史上最简单的一期omit.js
剔除对象中的属性点击了解本期详情一起参与。
终于有时间写下这篇文章的分享了,源码真的很简单,所以想在记忆还算清楚,赶紧记录下来。😂
在学习过程中,还不仅回顾了Javascript
的基础知识【深与浅拷贝】,还有如何在Vscode
调试index.test.js
中的例子,收益匪浅。还接触了最新的打包工具father
,让我们来看看吧👀
源码解析
// package.json代码片段
"scripts": {
"start": "father doc dev --storybook",
"build": "father doc build --storybook",
"compile": "father build",
"gh-pages": "father doc deploy",
"prepublishOnly": "npm run compile && np --yolo --no-publish",
"lint": "eslint .",
"test": "father test",
"coverage": "father test --coverage"
},
安装完node_modules
包,查看package.json
中的script命令,使用father
来进行项目管理,包括启动、构建、发布、单元测试等。
入口文件中,导出omit
函数,如下:
function omit(obj, fields) {
// eslint-disable-next-line prefer-object-spread
const shallowCopy = Object.assign({}, obj);
for (let i = 0; i < fields.length; i += 1) {
const key = fields[i];
delete shallowCopy[key];
}
return shallowCopy;
}
export default omit;
使用方法在README.md
中,写明了使用方法:
var omit = require('omit.js');
omit({ name: 'Benjy', age: 18 }, [ 'name' ]); // => { age: 18 }
从上面的使用及源码中可看出,函数可以接受两个参数,即原对象与需要剔除的属性,返回一个剔除了指定属性的浅拷贝的对象。
father包管理器
father
是新一代包管理工具,可以代替yarn or npm。npm指路
整理一下omit
库用到的father
命令,将按照类别区分如下:
docz内置文档
以下三行命令,将内置docz
文档配置。文档指路。
dev
模式将在开发环境下,展示项目中的.md
文档,本库中是README.md
文件,随后启动本地服务,在浏览器中就会看到如下图的界面:
build
模式将会本地构建.doc目录,可以将其目录下文件上传到服务器。
deploy
部署模式,将会自动部署到gitHub目录。
使用
deploy
之前请先执行build
命令,文档部署后域名为:https://yourname.github.io/your-repo
。
"start": "father doc dev --storybook",
"build": "father doc build --storybook",
"gh-pages": "father doc deploy"
build构建
打包命令,可以传入--config指定多种文件格式,并且可以映射入口文件为指定的文件名称。
"compile": "father build"
test单元测试
father
2.*.*版本内置了test
单元测试,但是看到参与开发的工程师在知乎上说明,在新版4.*版本已经不再内置这些工程化,用户可以更加灵活的添加单元测试。
"test": "father test",
"coverage": "father test --coverage" // 单元测试覆盖率
assert断言
omit
库使用assert断言,单元测试文件里的例子有两个(幸好这个仓库源码少,可以让我这么放肆的贴图😂)
import assert from 'assert';
import omit from '../src';
describe('omit', () => {
it('should create a shallow copy', () => {
const benjy = { name: 'Benjy' };
const copy = omit(benjy, []);
assert.deepEqual(copy, benjy);
assert.notEqual(copy, benjy);
});
it('should drop fields which are passed in', () => {
const benjy = { name: 'Benjy', age: 18 };
assert.deepEqual(omit(benjy, ['age']), { name: 'Benjy' });
assert.deepEqual(omit(benjy, ['name', 'age']), {});
});
});
说实话,当时看到第一个例子,不太明白什么使用assert.deepEqual()
和assert.notEqual()
都可以通过用例检测,觉得两个有点矛盾,后来去看了nodejs官网上的说明,有些明白了。
前者会遍历对象所有自身的且可枚举的属性,进行比较,即使用 ==
比较符。如下
import assert from 'node:assert';
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
notEqual()
使用==
比较符,如下:
import assert from 'node:assert';
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'
那经omit
函数返回的浅拷贝对象,可枚举属性值与原对象的是相等的,但是由于Object.assign的目标对象是个新{}
,使用==
也不再相等。
深拷贝与浅拷贝
既然函数中使用了Object.assign()
进行浅拷贝,再回顾一下他们之间的区别。
区别
深浅拷贝是针对Javascript
中的引用类型而言,因为引用类型比较特殊,浅拷贝仅仅复制了一份引用类型在内存中的地址,两个对象的改变会同步。深拷贝将会完全创造一个新的对象,内存地址不再指向同一份内存地址,对象改变不再互相影响。
Object.assign
Object.assign()
是浅拷贝,如果对象中有嵌套的对象,那拷贝的对象会随原对象发生变化。
Vscode调试技巧
最后一点点,是如何在Vscode中调试代码。
配置 auto-attach
在Vscode
中按 ctrl + shift + p
,打开输入 >auto attach
。默认是智能(smart
)
然后在本库中运行npm run test
,或者将鼠移入package.json
的scripts上方,会出现【调试】的提示。在需要的位置打断点,并运行命令进行调试,Vscode
界面将入进入断点模式。左侧面板会有函数调用栈、变量、断点,和在Chrome
开发者工具上非常相似。
结尾
在学习omit
库的最开始,只注意到了导出函数的使用,没有关注单元测试、调试等这些内容,看看别的同学学习的都很深入,自己也应该多了解,多翻阅文档。
分享今天看到的一句话
行动比思想有时候更重要。
所以,想做什么,现在就去做吧,从此刻开始🤞
还有最近在看的书单【尘埃落定】一部荣获茅盾文学奖的长篇小说,有喜欢的我们可以一起分享呀🎉