Lodash源码阅读-copySymbolsIn

Lodash 源码阅读-copySymbolsIn

概述

copySymbolsIn 是 Lodash 库中的一个内部工具函数,主要用于将源对象的自身和继承的可枚举 Symbol 属性复制到目标对象中。它是对象复制操作中处理 Symbol 类型属性的重要组成部分,特别是在需要考虑继承属性的深度克隆中发挥作用。

前置学习

依赖函数

  • copyObject:一个复制对象属性的基础函数,将源对象的属性复制到目标对象
  • getSymbolsIn:获取对象自身和继承的可枚举 Symbol 属性的函数,会遍历整个原型链
  • Object 构造器:在未提供目标对象时用于创建空对象

技术知识

  • ES6 Symbol:JavaScript 中的原始数据类型,用作对象属性的唯一标识符
  • 原型链(Prototype Chain):JavaScript 对象继承机制,对象可以从原型链继承属性和方法
  • 对象复制:JavaScript 中对象的浅拷贝和深拷贝概念与实现方式
  • 属性描述符:JavaScript 中对象属性的特性,如可枚举性、可写性等

源码实现

javascript 复制代码
/**
 * Copies own and inherited symbols of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy symbols from.
 * @param {Object} [object={}] The object to copy symbols to.
 * @returns {Object} Returns `object`.
 */
function copySymbolsIn(source, object) {
  return copyObject(source, getSymbolsIn(source), object);
}

实现思路

copySymbolsIn 函数的实现思路非常直接明了:

  1. 调用 getSymbolsIn(source) 获取源对象及其原型链上的所有可枚举 Symbol 属性
  2. 将这些 Symbol 属性作为要复制的属性列表,传递给 copyObject 函数
  3. copyObject 函数负责将这些 Symbol 属性从源对象复制到目标对象
  4. 最终返回修改后的目标对象

这种实现方式利用了函数组合的思想,将获取 Symbol 和复制属性的功能分离,使代码更简洁清晰。

源码解析

函数签名

javascript 复制代码
function copySymbolsIn(source, object) {

函数接收两个参数:

  • source:源对象,要从中复制 Symbol 属性的对象
  • object:目标对象,要将 Symbol 属性复制到的对象(可选)

如果不提供 object 参数,copyObject 函数会创建一个新的空对象。

函数体

javascript 复制代码
return copyObject(source, getSymbolsIn(source), object);

这行代码包含了函数的全部逻辑,可以分解为以下步骤:

  1. getSymbolsIn(source):调用 getSymbolsIn 函数,获取源对象及其原型链上的所有可枚举 Symbol 属性数组
  2. copyObject(source, symbolsArray, object):调用 copyObject 函数,将获取到的 Symbol 属性从源对象复制到目标对象
    • source:源对象,提供属性值
    • symbolsArray:要复制的属性数组,这里是所有 Symbol 属性
    • object:目标对象,接收复制的属性

copyObject 函数的工作方式是遍历提供的属性数组(这里是 Symbol 属性数组),将每个属性从源对象复制到目标对象,并返回修改后的目标对象。

与 copySymbols 的对比

copySymbolsIncopySymbols 的主要区别在于:

javascript 复制代码
// copySymbols 仅复制对象自身的 Symbol 属性
function copySymbols(source, object) {
  return copyObject(source, getSymbols(source), object);
}

// copySymbolsIn 复制对象自身和继承的 Symbol 属性
function copySymbolsIn(source, object) {
  return copyObject(source, getSymbolsIn(source), object);
}

区别仅在于使用 getSymbols 还是 getSymbolsIn 来获取 Symbol 属性:

  • getSymbols 只获取对象自身的可枚举 Symbol 属性
  • getSymbolsIn 获取对象自身和继承的可枚举 Symbol 属性

这种区别对应了 JavaScript 中浅拷贝和深拷贝的不同需求。

总结

copySymbolsIn 函数是 Lodash 中一个短小精悍但功能强大的工具函数,它通过组合使用 getSymbolsIncopyObject 两个函数,实现了对象自身和继承的 Symbol 属性的复制。

这个函数的实现体现了几个软件设计原则:

  1. 单一职责原则:函数只负责一件事------复制 Symbol 属性,而获取 Symbol 和实际的复制操作则委托给其他专门的函数
  2. 函数组合 :通过组合 getSymbolsIncopyObject 这两个基础函数来构建更复杂的功能
  3. 抽象合理:提供了适当级别的抽象,使调用者不需要关心 Symbol 属性的获取和复制细节
  4. 接口一致性 :与 copySymbols 函数保持一致的接口,方便开发者在不同场景下选择合适的工具

在现代 JavaScript 开发中,随着 Symbol 的广泛使用,特别是在框架和库的内部实现中,copySymbolsIn 这样的工具函数变得越来越重要,它确保了在处理对象时不会遗漏这些特殊的属性,包括那些来自原型链的属性。

相关推荐
阿懂在掘金14 分钟前
早点下班(Vue2.7版):旧项目也能少写 40%+ 异步代码
前端·vue.js·开源
Mintopia15 分钟前
Web性能测试流程全解析:从概念到落地的完整指南
前端·性能优化·测试
用户57573033462432 分钟前
JavaScript 原型继承全解析:从 call/apply 到寄生组合式继承
javascript
Qinana37 分钟前
第一次用向量数据库!手搓《天龙八部》RAG助手,让AI真正“懂”你
前端·数据库·后端
忆江南37 分钟前
# Flutter Engine、Dart VM、Runner、iOS 进程与线程 —— 深度解析
前端
龙国浪子42 分钟前
从「选中一段」到「整章润色」:编辑器里的 AI 润色是怎么做出来的
前端·人工智能
小码哥_常1 小时前
Android 开发秘籍:用Tint为Icon动态变色
前端
小码哥_常1 小时前
从0到1手把手封装Android基类Activity/Fragment,告别重复代码,开发效率直接拉满!
前端
ChoriaKiinweill1 小时前
不会有人现在还不了解BOM的知识吧? 关于它的一切都在这里!!!
前端
ChoriaKiinweill1 小时前
我们最爱操纵的DOM是个什么玩意? 关于DOM的知识快速一览!
前端