【第36期】| omit.js 剔除对象中的属性

186 阅读2分钟

本文参加了由公众号@若川视野 发起的每周源码共读活动,  点击了解详情一起参与。

这是源码共读的第36期

在学习或者工作中,会遇到使用一个对象但却不需要对象某个或某些属性的场景。此时,大多数会使用delete直接删除对象的属性,但delete之后,对象的这个属性消失了,如果在其他时候需要使用的时候就没办法了。所以,更好解决方案是,拷贝这个对象所有需要用到的属性,去除某个或某些不需要的属性,而这就是omit.js所做的事情,让我们一起看看吧!

准备工作

  1. git地址
https://github.com/benjycui/omit.js
  1. 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)
  }
}
  1. 使用深拷贝代替浅拷贝
  2. 进行了错误的捕获与默认参数的传递

总结

  1. 了解了omit.js这个工具库
  2. 加深了对Object.assign()的理解