最简单源码 omit.js 剔除对象中的属性解读

科学上网

  • 克隆github的项目,需要配置git bash的代理,否则容易超时无法连接,在git bash中输入以下命令,后面的地址是我本地的代理地址,更换为自己的
bash 复制代码
git config ---global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

克隆项目

  • 这里直接克隆了omit.js的源码, 并使用 Visual Studio Code 打开
bash 复制代码
git clone https://github.com/benjycui/omit.js.git

运行项目

  • Visual Studio Code 中打开一个终端
bash 复制代码
# 安装依赖
npm install

# 执行测试用例
npm run test
  • 根据结果显示,通过了一个测试集合,2个测试案例。

查看测试内容

js 复制代码
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']), {});
  });
});
  • 查看源码, 打开src/index.js文件,里面便是omit.js的源码,只有11行。

看了一下源码,有以下几个问题

  • 问题1:第3行为什么要对传入的参数obj进行浅拷贝?

思考:平时写代码时,没有关注过这个,删除对象属性时直接使用delete就删除了,用着也没问题。然后就是将这行 浅拷贝 删除, 直接在参数obj上修改,进过测试,第一个测试用例中assert.notEqual(copy, benjy)无法通过,但是这也不影响剔除对象属性。思来想去,后面想到如果传入的obj,在后续的代码中需要使用,但此时obj已经发生改变,已经不是之前的obj了。代码解释如下:

js 复制代码
// 初始化一个对象,直接删除属性,不进行浅拷贝
const obj = {num: 1, sum: 0, init: 0 }
const copy = obj

// 剔除对象属性
delete copy['init']

// 对obj进行操作
obj['sum'] = obj['num'] + obj['init']

// 打印obj
console.log(obj)  // { num: 1, sum: NaN }
js 复制代码
// 初始化一个对象
const obj = {num: 1, sum: 0, init: 0 }

// 进行浅拷贝
const copy = Object.assign({}, obj)

// 剔除对象属性
delete copy['init']

// 对obj进行操作
obj['sum'] = obj['num'] + obj['init']

// 打印obj
console.log(obj)  // { num: 1, sum: 1, init: 0 }

举得例子可能有些生硬,总之如果确定该对象上的属性,后续不会再使用,可以直接删,改变原对象的属性。突然想起js的原生方法中,数组的循环 filter, map 均不会改变原数组。

  • 问题2: 平时写项目时,拷贝对象都是使用的扩展运算符,想知道这两种方法的区别?这里参考群里底层的原文章
  1. 对象合并,数组合并,Object.assign、connat的性能会比展开运算符"..."的性能高。
  2. Object.assign会触发Proxy/Object.definedProperty的set方法,展开运算符"..."不会触发。
  3. 它两都是浅拷贝。
  4. 合并对象、数组的时候,展开运算符放在前面的性能比放在后面的性能高。
  5. 不定参数的时候,有自己的使用方式。
  6. Object.assign 可以兼容es5,扩展运算符只能es6之后使用。
  • 问题3:delete删除一个对象中,不存在的属性会发生什么?

不会发生什么,即使不存在也会返回true

总结

基础还是太薄弱了,还是要多多思考,多总结。

相关推荐
易保山2 天前
聊聊 Glide | 不看源码,只聊设计
开源·源码阅读·glide
F_Director5 天前
傻子都能理解的 React Hook 闭包陷阱
前端·react.js·源码阅读
阿迪卡多5 天前
5.5 接收器遮挡 (Receiver Shading) 详细解析
源码阅读
南风lof8 天前
源码赏析:Java线程池中的那些细节
java·源码阅读
Tang102411 天前
Kotlin 异步编程的核心-协程状态机
源码阅读
苏近之14 天前
如何为 Python 新增语法
python·源码阅读·编译原理
SunStriKE24 天前
SgLang代码细读-3. Cache
llm·源码阅读·推理
SunStriKE1 个月前
SgLang代码细读-2.forward过程
深度学习·llm·源码阅读·推理
CYRUS STUDIO1 个月前
FART 自动化脱壳框架简介与脱壳点的选择
android·驱动开发·自动化·逆向·源码阅读·脱壳
都叫我大帅哥2 个月前
Spring 源码解析:postProcessBeanFactory() 方法深度剖析与面试指南
java·spring·源码阅读