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

相关推荐
萌萌哒草头将军5 小时前
⚡⚡⚡尤雨溪宣布开发 Vite Devtools,这两个很哇塞 🚀 Vite 的插件,你一定要知道!
前端·vue.js·vite
游离状态的猫16 小时前
JavaScript性能优化实战:从瓶颈定位到极致提速
开发语言·javascript·性能优化
小彭努力中6 小时前
7.Three.js 中 CubeCamera详解与实战示例
开发语言·前端·javascript·vue.js·ecmascript
浪裡遊7 小时前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
滿7 小时前
Vue3 Element Plus el-tabs数据刷新方法
javascript·vue.js·elementui
LinDaiuuj7 小时前
判断符号??,?. ,! ,!! ,|| ,&&,?: 意思以及举例
开发语言·前端·javascript
敲厉害的燕宝7 小时前
Pinia——Vue的Store状态管理库
前端·javascript·vue.js
Aphasia3117 小时前
react必备JavaScript知识点(二)——类
前端·javascript
玖玖passion7 小时前
数组转树:数据结构中的经典问题
前端
呼Lu噜7 小时前
WPF-遵循MVVM框架创建图表的显示【保姆级】
前端·后端·wpf