初体验【源码共读 第36期】omit.js 剔除对象中的属性

158 阅读1分钟

omit 源码解析

功能:返回一个剔除掉指定属性的新的对象

/**
 * 
 * @param {object} obj 待处理的对象
 * @param {Array} fields 需要剔除的属性集合
 * @returns 
 */
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;

安装 & 运行

npm init -y
npm i --save omit.js

新建一个 index.js

const omit = require('omit.js')
let obj = {
  name: "kwg",
  age: 30,
  address: {
    id: 1,
    desc: "江苏"
  }
}
console.log(omit.default(obj, ['age'])); // { name: 'kwg', address: { id: 1, desc: '江苏' } }

可以通过 node 命令直接运行查看结果 node index.js

测试用例

通过执行 npm run test 查看用例执行吧结果

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']), {});
  });
});

image.png

思考

  1. 当前方法不支持深度属性剔除,可以通过传入一个path,进行匹配删除 'address.name'
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];
  // }
  fields.forEach(field => {
    // 表示这是一个 path
    if (field.indexOf('.')) {
      let key = `.${field}`
      // eval 需要对输入项进行严格校验,防止注入攻击
      try {
        if(eval(`shallowCopy${key}`)){
          eval(`delete shallowCopy${key}`)
        }
      } catch (error) {
        
      }
    } else {
      const key = fields[i];
      delete shallowCopy[key];
    }
  })
  return shallowCopy;
}

  1. 不支持import导入,可以修改package.json 增加 "type": "module" 尝试
  2. father 还不熟悉,有机会可以了解一下