omit.js - 极简的对象属性过滤工具

80 阅读3分钟

查看源码库 README

安装 & 使用方式

npm i --save omit.js
var omit = require('omit.js');
omit({ name: 'Benjy', age: 18 }, [ 'name' ]); // => { age: 18 }

API

omit(objObjectfieldsstring[]): Object

只有一个方法,README 里 “Return a shallow copy which had dropped fields.” 这句话总结了其实现,就是对 obj 对象进行一层浅复制,然后遍历丢弃 fields 数组的属性。

查看 package.json

{
  "main": "lib/index.js", // cjs 格式文件入口
  "module": "es/index.js", // esm 格式文件入口
  "types": "index.d.ts", // types
  "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"
  },
  "devDependencies": {
    "@umijs/fabric": "^2.2.2", // umijs 提供的 prettier、eslint、styelint 风格配置合集
    "assert": "^1.4.1", // 单元测试断言
    "eslint": "^7.4.0", // eslint 代码风格规范化
    "father": "^2.29.5", // umijs的 npm 库开发工具,阿里系
    "np": "^6.3.1", // 比官方 npm publish 更友好的 npm 包发布工具
    "rc-tools": "^6.3.3" // ant-design 团队提供的 react-components 系列开发工具,维护已不活跃
  }
}

father

package.json 的 scripts 可以看到,father 这个工具支撑了该仓库几乎全部 tasks,umijs 团队这个工具还是很强大的,最新版本(2023-07-30)具备以下特性:

![[Pasted image 20230730163813.png]]

我们执行 npm run compile 任务,会发现打包输出的产物,包含了 cjs 和 esm 两种模块化风格的产物(分别生成在 lib、es 目录),这些都是 father 工具内部支持的特性,只需要再 .fatherrc.js 文件添加配置即可

// .fatherrc.js
export default {
  entry: ['src/index.js'], // 打包入口
  cjs: 'babel', // cjs 模块风格打包
  esm: { type: 'babel', importLibToEs: true }, // esm 模块风格打包
  doc: { base: '/switch' }, // docz 文档配置
  preCommit: {
    eslint: true,
    prettier: true,
  },
};

单元测试用例

了解 omit.js 库的功能,可以先从其单元测试入手,因为这往往代表了这个库的 test-case 设计与边界场景,位于 tests/index.test.js 文件,使用 asserts 断言库进行单元测试:

import assert from 'assert';
import omit from '../src';

describe('omit', () => {
  it('should create a shallow copy', () => {
    const benjy = { name: 'Benjy' };
    const copy = omit(benjy, []);
    // 传递丢弃属性数组为空,判断是否原始对象与 omit 生成对象结构相同
    assert.deepEqual(copy, benjy);
    // 判断 omit 方法处理后,对象是否属于不同引用
    assert.notEqual(copy, benjy);
  });

  it('should drop fields which are passed in', () => {
    const benjy = { name: 'Benjy', age: 18 };
	// 丢弃部部属性,判断是否原始对象与 omit 生成对象结构相同
    assert.deepEqual(omit(benjy, ['age']), { name: 'Benjy' });
    // 丢弃全部属性,判断是否原始对象与 omit 生成对象结构相同
    assert.deepEqual(omit(benjy, ['name', 'age']), {});
  });
});

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;
}

代码是比较简单的,使用 Object.assign 进行对象的浅复制,然后遍历 fields 数组里的属性,在浅复制后的对象进行 delete 操作,从而将指定属性丢弃移除。但这个库是支持第一层的属性丢弃移除,嵌套深层次则无效。

总结

通过翻看 omit.js 源码库,学习了其代码构建实现,father 工具使用构建多模块化的产物,npm 包发布之前可以使用 prepublishOnly 钩子使用一些自定义任务, np 是更友好易用的 npm 包发布工具。