Lodash源码阅读-baseAssignValue

Lodash 源码阅读-baseAssignValue

功能概述

baseAssignValue 是 Lodash 中的一个内部工具函数,用于将值赋给对象的属性,是 assignValue 的基础实现版本。它的特点是直接赋值,不进行任何相等性检查,同时对 __proto__ 属性有特殊处理,以防止原型污染攻击。

前置学习

依赖函数

  • defineProperty :对象属性定义工具,用于安全地处理 __proto__ 属性

技术知识

  • 对象属性赋值:JavaScript 中对象属性的赋值机制
  • 原型污染攻击 :通过修改 __proto__ 属性导致的安全问题
  • Object.defineProperty:JavaScript 中定义或修改对象属性的 API

源码实现

javascript 复制代码
function baseAssignValue(object, key, value) {
  if (key == "__proto__" && defineProperty) {
    defineProperty(object, key, {
      configurable: true,
      enumerable: true,
      value: value,
      writable: true,
    });
  } else {
    object[key] = value;
  }
}

实现思路

baseAssignValue 的实现思路非常直接:

  1. 首先检查要赋值的键名是否为 __proto__,这是一个特殊的键,需要特殊处理

    • 如果是 __proto__ 且存在 defineProperty 方法(即环境支持 Object.defineProperty),则使用 defineProperty 安全地设置该属性
    • 这么做是为了防止原型链污染攻击,保证操作的安全性
  2. 如果不是 __proto__ 或环境不支持 defineProperty,就直接使用赋值运算符 = 设置属性

    • 这是 JavaScript 中最基本的属性赋值方式

源码解析

让我们逐行分析 baseAssignValue 函数的实现:

javascript 复制代码
function baseAssignValue(object, key, value) {

函数定义,接收三个参数:

  • object:要修改的目标对象
  • key:要设置的属性名
  • value:要赋的值
javascript 复制代码
  if (key == '__proto__' && defineProperty) {

第一个条件检查,判断:

  1. 属性名是否为 __proto__(注意这里使用的是宽松相等 ==,所以会做类型转换)
  2. defineProperty 是否可用(在 Lodash 内部,defineProperty 是对 Object.defineProperty 的引用或自定义实现)

这个检查很重要,因为 __proto__ 是一个特殊属性,直接设置它可能导致原型链污染,产生安全风险。

javascript 复制代码
defineProperty(object, key, {
  configurable: true,
  enumerable: true,
  value: value,
  writable: true,
});

如果条件满足,使用 defineProperty 安全地定义该属性,并设置属性描述符:

  • configurable: true:允许属性被删除或重新配置
  • enumerable: true:允许属性在对象的属性枚举中出现
  • value: value:设置属性的值为传入的 value
  • writable: true:允许属性的值被修改

这种方式比直接赋值更安全,特别是对于 __proto__ 这样的特殊属性。

javascript 复制代码
  } else {
    object[key] = value;
  }

如果不是 __proto__ 属性或环境不支持 defineProperty,则直接使用标准的属性赋值语法。这是处理常规属性的快速路径。

原型污染问题

最新版的 Chrome 浏览器中暂时没有用代码验证出来

与 assignValue 的关系

baseAssignValueassignValue 的基础实现。assignValue 在调用 baseAssignValue 前会进行额外的检查:

javascript 复制代码
function assignValue(object, key, value) {
  var objValue = object[key];
  if (
    !(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
    (value === undefined && !(key in object))
  ) {
    baseAssignValue(object, key, value);
  }
}

assignValue 会:

  1. 检查对象是否已有同名且值相等的属性(使用 eq 判断)
  2. 检查值是否为 undefined 且对象上不存在该属性

只有当需要更新值时,才会调用 baseAssignValue 进行实际赋值操作。

总结

baseAssignValue 是 Lodash 内部的一个基础工具函数,用于安全地为对象设置属性值。

相关推荐
番茄比较犟10 分钟前
Combine知识点switchToLatest
前端
北京_宏哥11 分钟前
🔥《爆肝整理》保姆级系列教程-玩转Charles抓包神器教程(15)-Charles如何配置反向代理
前端·面试·charles
Process14 分钟前
前端图片技术深度解析:格式选择、渲染原理与性能优化
前端·面试·性能优化
大松鼠君15 分钟前
轿车3D展示
前端·webgl·three.js
却尘15 分钟前
URL参数传递的两种方式:查询参数与路径参数详解
前端
下辈子再也不写代码了17 分钟前
分片下载、断点续传与实时速度显示的实现方法
前端·后端·github
婷婷婷婷18 分钟前
AntV X6 常用方法
前端
LucianaiB27 分钟前
拿到Offer,租房怎么办?看我用高德MCP+腾讯云MCP,帮你分分钟搞定!
前端·后端·cursor
用户175923421502833 分钟前
D3.js - 基本用法
前端·d3.js
Mr.Liu61 小时前
小程序30-wxml语法-声明和绑定数据
前端·微信小程序·小程序