本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
这是源码共读的第36期
在学习或者工作中,会遇到使用一个对象但却不需要对象某个或某些属性的场景。此时,大多数会使用delete直接删除对象的属性,但delete之后,对象的这个属性消失了,如果在其他时候需要使用的时候就没办法了。所以,更好解决方案是,拷贝这个对象所有需要用到的属性,去除某个或某些不需要的属性,而这就是omit.js所做的事情,让我们一起看看吧!
准备工作
- git地址
https://github.com/benjycui/omit.js
- omit.js的意思 :用于创建已删除某些字段的对象的浅表副本的实用函数。
源码分析
function omit(obj, fields) {
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;
首先使用了Object.assign()对源对象obj进行一次浅拷贝,然后遍历需要删除属性的数组fields,通过遍历出的数组项,来对浅拷贝出来的shallowCopy对象进行相对应属性的删除。
用例测试:
var omit = require('omit.js'); omit({ name: 'Benjy', age: 18 }, [ 'name' ]); // => { age: 18 }
思考:
1.这里使用的是浅拷贝的方式,如果源对象的属性是对象类型,那么如果该属性没有进行删除,当源对象或者拷贝出的对象进行对该属性进行修改时,另一者也会随着发生改变,可能会对后续的操作产生一定的影响。
2.默认fields参数传入的是数组,但是一般情况下,删除单一属性的时候习惯于使用字符串进行删除(我的习惯),而且不排除有人使用时没人传入参数,或者是使用时该参数传入其它值,如数字时,就会报错,且本身没对报错进行捕获。
尝试改进:
function omit(obj, fields = '') {
const _copyObj = JSON.parse(JSON.stringify(obj))
if(!fields) return _copyObj
try{
let _arr = []
Array.isArray(fields)
? _arr=fields
: typeof fields=== 'string'
? _arr.push(fields)
: _arr = []
// eslint-disable-next-line prefer-object-spread
for (let i = 0; i < _arr.length; i += 1) {
const key = _arr[i];
delete _copyObj[key];
}
return _copyObj;
}catch(err){
throw new Error(err)
}
}
- 使用深拷贝代替浅拷贝
- 进行了错误的捕获与默认参数的传递
总结
- 了解了omit.js这个工具库
- 加深了对Object.assign()的理解