Lodash 源码阅读-copySymbols
概述
copySymbols
是 Lodash 库中的一个内部工具函数,主要用于将源对象的自身可枚举 Symbol 属性复制到目标对象中。在 JavaScript 中处理对象复制时,它确保了 Symbol 类型的属性也能被正确地复制,这在标准的对象复制方法中容易被忽略。
前置学习
依赖函数
- copyObject:一个基础的对象属性复制函数,负责将属性从源对象复制到目标对象
- getSymbols:获取对象自身可枚举 Symbol 属性的函数,不包括继承的属性
- Object 构造器:在未提供目标对象时用于创建空对象
技术知识
- ES6 Symbol:JavaScript 中的原始数据类型,用作对象属性的唯一标识符
- 可枚举属性:JavaScript 对象属性的特性之一,决定该属性是否会出现在对象的枚举中
- 对象复制:JavaScript 中对象的浅拷贝和属性转移的概念与实现
- 函数组合:通过组合多个单一功能的函数构建更复杂功能的编程模式
源码实现
javascript
/**
* Copies own 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 copySymbols(source, object) {
return copyObject(source, getSymbols(source), object);
}
实现思路
copySymbols
函数的实现思路十分清晰简洁:
- 调用
getSymbols(source)
获取源对象中所有自身的可枚举 Symbol 属性 - 将这些 Symbol 属性作为要复制的属性列表,传递给
copyObject
函数 copyObject
函数负责将这些 Symbol 属性从源对象复制到目标对象- 最终返回修改后的目标对象
这种实现方式体现了"组合胜于继承"的设计理念,通过组合使用 getSymbols
和 copyObject
这两个专门的函数,实现了 Symbol 属性的复制功能。
源码解析
函数签名
javascript
function copySymbols(source, object) {
函数接收两个参数:
source
:源对象,要从中复制 Symbol 属性的对象object
:目标对象,要将 Symbol 属性复制到的对象(可选参数)
如果调用时不提供 object
参数,copyObject
函数会创建一个新的空对象作为目标对象。
函数体
javascript
return copyObject(source, getSymbols(source), object);
这行代码体现了函数的全部逻辑,可以分解为以下几个步骤:
getSymbols(source)
:调用getSymbols
函数,获取源对象的所有自身可枚举 Symbol 属性,返回一个数组copyObject(source, symbolsArray, object)
:调用copyObject
函数,将获取到的 Symbol 属性从源对象复制到目标对象source
:源对象,提供属性值的来源symbolsArray
:要复制的属性列表,这里是所有 Symbol 属性object
:目标对象,接收复制的属性
copyObject
函数的工作原理是遍历提供的属性数组(这里是 Symbol 属性数组),将每个属性从源对象复制到目标对象,并最终返回修改后的目标对象。
与 copySymbolsIn 的比较
copySymbols
与 copySymbolsIn
函数的主要区别在于处理范围:
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);
}
两者的区别仅在于使用的获取 Symbol 属性的函数不同:
getSymbols
只获取对象自身的可枚举 Symbol 属性getSymbolsIn
获取对象自身和继承的可枚举 Symbol 属性(遍历整个原型链)
这种区别对应了不同的使用场景,特别是在需要决定是否复制继承属性时。
总结
copySymbols
是 Lodash 中一个简洁但非常实用的工具函数,它解决了 JavaScript 对象复制中容易被忽略的 Symbol 属性处理问题。通过组合 getSymbols
和 copyObject
这两个基础函数,提供了一种优雅的方式来复制对象的 Symbol 属性。
这个函数的实现体现了几个重要的软件设计原则:
- 单一职责原则:函数只专注于一件事------复制 Symbol 属性,而获取 Symbol 和实际复制操作分别委托给专门的函数
- 模块化设计:将复杂操作分解为更小、更专注的函数,使代码更容易理解和维护
- 函数组合:通过组合多个简单函数实现复杂功能,减少代码重复
- 一致性接口 :与
copySymbolsIn
保持相似的接口,方便开发者根据需要选择合适的工具
在现代 JavaScript 开发中,随着 Symbol 的广泛应用,特别是在库和框架的内部实现中,copySymbols
这样的工具函数变得越来越重要,它确保了在处理对象复制时不会遗漏这些特殊的属性类型。