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
函数的实现思路非常直接明了:
- 调用
getSymbolsIn(source)
获取源对象及其原型链上的所有可枚举 Symbol 属性 - 将这些 Symbol 属性作为要复制的属性列表,传递给
copyObject
函数 copyObject
函数负责将这些 Symbol 属性从源对象复制到目标对象- 最终返回修改后的目标对象
这种实现方式利用了函数组合的思想,将获取 Symbol 和复制属性的功能分离,使代码更简洁清晰。
源码解析
函数签名
javascript
function copySymbolsIn(source, object) {
函数接收两个参数:
source
:源对象,要从中复制 Symbol 属性的对象object
:目标对象,要将 Symbol 属性复制到的对象(可选)
如果不提供 object
参数,copyObject
函数会创建一个新的空对象。
函数体
javascript
return copyObject(source, getSymbolsIn(source), object);
这行代码包含了函数的全部逻辑,可以分解为以下步骤:
getSymbolsIn(source)
:调用getSymbolsIn
函数,获取源对象及其原型链上的所有可枚举 Symbol 属性数组copyObject(source, symbolsArray, object)
:调用copyObject
函数,将获取到的 Symbol 属性从源对象复制到目标对象source
:源对象,提供属性值symbolsArray
:要复制的属性数组,这里是所有 Symbol 属性object
:目标对象,接收复制的属性
copyObject
函数的工作方式是遍历提供的属性数组(这里是 Symbol 属性数组),将每个属性从源对象复制到目标对象,并返回修改后的目标对象。
与 copySymbols 的对比
copySymbolsIn
与 copySymbols
的主要区别在于:
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 中一个短小精悍但功能强大的工具函数,它通过组合使用 getSymbolsIn
和 copyObject
两个函数,实现了对象自身和继承的 Symbol 属性的复制。
这个函数的实现体现了几个软件设计原则:
- 单一职责原则:函数只负责一件事------复制 Symbol 属性,而获取 Symbol 和实际的复制操作则委托给其他专门的函数
- 函数组合 :通过组合
getSymbolsIn
和copyObject
这两个基础函数来构建更复杂的功能 - 抽象合理:提供了适当级别的抽象,使调用者不需要关心 Symbol 属性的获取和复制细节
- 接口一致性 :与
copySymbols
函数保持一致的接口,方便开发者在不同场景下选择合适的工具
在现代 JavaScript 开发中,随着 Symbol 的广泛使用,特别是在框架和库的内部实现中,copySymbolsIn
这样的工具函数变得越来越重要,它确保了在处理对象时不会遗漏这些特殊的属性,包括那些来自原型链的属性。