Lodash源码阅读-property

Lodash 源码阅读-property

概述

property 是 Lodash 中的函数式编程工具,用来创建一个属性访问器函数。这个函数接收对象,返回对象指定路径上的属性值。它能够大大简化数据操作过程,特别是在处理复杂的对象集合时非常有用。

前置学习

依赖函数

  • isKey:判断传入的值是否为简单属性键(而非复杂路径)
  • toKey:将值转换为有效的对象属性键
  • baseProperty:基础函数,用于访问对象的单层属性
  • basePropertyDeep:基础函数,用于访问对象的深层嵌套属性

技术知识

  • 高阶函数:返回函数的函数,property 返回的是一个函数
  • 属性路径 :访问嵌套对象的路径表示,如 'user.profile.name'['user', 'profile', 'name']
  • 策略模式:根据输入类型选择不同的处理策略
  • 函数式编程:纯函数、无副作用、函数组合等理念

源码实现

javascript 复制代码
function property(path) {
  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
}

实现思路

property 函数的实现非常简洁明了:

  1. 接收一个路径参数 path,可以是字符串、数组或符号
  2. 判断路径是否为简单属性键(使用 isKey 函数)
  3. 如果是简单属性键(如 'name'),使用 baseProperty 创建简单访问器
  4. 如果是复杂路径(如 'user.profile.name' 或数组),使用 basePropertyDeep 创建深层访问器
  5. 返回创建的访问器函数,该函数可以传入对象来获取属性值

这种分治策略根据路径的复杂度选择最优的实现方式,既保证了功能完整性,又考虑了性能优化。

源码解析

路径类型判断

javascript 复制代码
isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);

函数使用 isKey 判断路径类型,其判断逻辑主要包括:

javascript 复制代码
function isKey(value, object) {
  if (isArray(value)) {
    return false;
  }
  var type = typeof value;
  if (
    type == "number" ||
    type == "symbol" ||
    type == "boolean" ||
    value == null ||
    isSymbol(value)
  ) {
    return true;
  }
  return (
    reIsPlainProp.test(value) ||
    !reIsDeepProp.test(value) ||
    (object != null && value in Object(object))
  );
}
  • 数组形式的路径肯定是复杂路径
  • 数字、符号、布尔值、null 或 undefined 被视为简单键
  • 不包含特殊字符(如 .[)的字符串为简单键
  • 如果是对象的直接属性,也视为简单键

处理简单属性键

当路径是简单属性键时,使用 baseProperty 创建属性访问器:

javascript 复制代码
function baseProperty(key) {
  return function (object) {
    return object == null ? undefined : object[key];
  };
}

这个函数:

  • 返回一个接收对象的新函数
  • 检查对象是否为 null 或 undefined
  • 直接使用方括号语法 object[key] 访问属性
  • 返回对应的属性值或 undefined

处理复杂属性路径

当路径是复杂路径时,使用 basePropertyDeep 创建深层属性访问器:

javascript 复制代码
function basePropertyDeep(path) {
  return function (object) {
    return baseGet(object, path);
  };
}

basePropertyDeep 同样返回一个函数,但内部使用 baseGet 来处理嵌套属性访问:

javascript 复制代码
function baseGet(object, path) {
  path = castPath(path, object);

  var index = 0,
    length = path.length;

  while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }
  return index && index == length ? object : undefined;
}

baseGet 函数:

  • 将路径标准化为数组
  • 循环遍历路径的每一段
  • 逐层访问对象的嵌套属性
  • 处理 null 和 undefined 值
  • 返回最终结果或 undefined

性能优化

property 函数的实现体现了性能优化:

  • 对于简单属性键,使用更直接高效的 baseProperty
  • 对于复杂路径,使用功能更完整的 basePropertyDeep
  • 避免在简单情况下进行不必要的路径解析和处理

总结

property 函数虽然实现简单,但它是 Lodash 中极其实用的工具函数,体现了几个重要的设计原则:

  1. 简洁接口:以单一参数创建强大的属性访问器
  2. 策略模式:根据路径类型智能选择最优实现
  3. 函数式设计:返回纯函数,支持函数组合,无副作用
  4. 性能优化:区分简单和复杂情况,提供专门优化
  5. 代码复用:利用基础函数构建更高级的抽象

这个函数展示了 Lodash 如何用简单的函数创建强大的工具,使开发者能够以更简洁、更声明式的方式处理数据。它是函数式编程在 JavaScript 中的绝佳实践案例,通过组合小型专用函数构建出灵活而强大的应用。

相关推荐
zandy101118 分钟前
如何快速入门-衡石科技分析平台
服务器·前端·科技·数据库管理员
邝邝邝邝丹1 小时前
React学习———React Router
前端·学习·react.js
Yvonne爱编码1 小时前
CSS- 2.1 实战之图文混排、表格、表单
前端·css·html·github·状态模式·html5·hbuilder
前端小巷子1 小时前
CSS面试题汇总
前端·css·面试
绝美焦栖1 小时前
vue复杂数据类型多层嵌套的监听
前端·javascript·vue.js
xixixin_2 小时前
【Vite】前端开发服务器的配置
服务器·前端·网络
.生产的驴2 小时前
Vue3 加快页面加载速度 使用CDN外部库的加载 提升页面打开速度 服务器分发
运维·服务器·前端·vue.js·分布式·前端框架·vue
史迪仔01123 小时前
Python生成器:高效处理大数据的秘密武器
前端·数据库·python
蓝婷儿3 小时前
前端面试每日三题 - Day 34
前端·面试·职场和发展
CopyLower3 小时前
苹果计划将AI搜索集成至Safari:谷歌搜索下降引发的市场变革
前端·人工智能·safari