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 中的绝佳实践案例,通过组合小型专用函数构建出灵活而强大的应用。

相关推荐
haaaaaaarry15 分钟前
Element Plus常见基础组件(一)
java·前端·javascript·vue.js
qingyingWin30 分钟前
原生微信小程序研发,如何对图片进行统一管理?
前端·微信小程序
不懂英语的程序猿40 分钟前
【JEECG】JVxeTable表格拖拽排序功能
前端·后端
拾光拾趣录1 小时前
前端灵魂拷问:从URL到Redux,17个常见问题
前端·面试
萌萌哒草头将军1 小时前
Prisma ORM 又双叒叕发布新版本了!🚀🚀🚀
前端·javascript·node.js
mldong1 小时前
推荐一款超高颜值的后台管理模板!Art-Design-Pro!开源!免费!
前端·vue.js·架构
草字1 小时前
uniapp 如果进入页面输入框自动聚焦,此时快速返回页面或者跳转到下一个页面,输入法顶上来的页面出现半屏的黑屏问题。
java·前端·uni-app
我是ed.2 小时前
cocos Js 使用 webview 通过 postMessage 进行通信
开发语言·javascript·ecmascript
程序视点2 小时前
Wise Duplicate Finder 重复文件查找工具 - 永久免费专业版文件去重工具
前端·windows
一点一木2 小时前
🚀 2025 年 07 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github