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 这样的工具函数变得越来越重要,它确保了在处理对象时不会遗漏这些特殊的属性,包括那些来自原型链的属性。

相关推荐
不在逃避q23 分钟前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁37 分钟前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One98542 分钟前
高进度算法模板速记(待完善)
java·前端·算法
陈随易1 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师2 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174462 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈2 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen3 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒3 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端
梅孔立4 小时前
两种免费的翻译API调用方式详解 - Edge官方API与个人缓存服务
前端·缓存·edge