merge函数

 function merge(target,source){
for (let key in source){
if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}
}
} let o1 ={}
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1,o2)
console.log(o1.a, o1.b)//1 2
o3 ={}
console.log(o3.b)//2

这段函数我看了半天没理解,交给ai一段一段理解,首先关于merge函数的判断

 if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}

ai给出的解释是这样的

 提供的代码片段似乎是一个合并函数的一部分,目的是将 source 对象中的属性合并到 target 对象中。以下是代码的简要解释:

条件检查:代码检查给定的 key 是否同时存在于 source 和 target 对象中。
递归合并:如果 key 在两个对象中都存在,则调用 merge 函数(可能在其他地方定义)递归地合并这两个对象中该键的值。
赋值操作:如果 key 只在 source 中存在,则将 source 中的该键值直接赋值给 target 对象。

我们举例说明

 假设我们有两个对象 source 和 target,它们的结构如下:
 let source = {
a: 1,
b: {
x: 10,
y: 20
},
c: 3
};

let target = {
b: {
x: 5
},
d: 4
};
 这个时候我们希望将 source 对象的属性合并到 target 对象中。
 ​
 代码示例
 function merge(target, source) {
for (let key in source) {
if (key in source && key in target) {
merge(target[key], source[key]); // 递归合并
} else {
target[key] = source[key]; // 直接赋值
}
}
}

merge(target, source);
console.log(target);
 合并步骤解析
 处理 a:

a 在 source 中存在,但在 target 中不存在,因此直接赋值。target 变为:
{
b: { x: 5 },
d: 4,
a: 1
}
处理 b:

b 在 source 和 target 中都存在,进行递归合并。
进入 merge(target.b, source.b):
x 在 source.b 和 target.b 中都存在,递归合并。
y 在 source.b 中存在,但 target.b 中不存在,因此直接赋值。
结果为:
{
x: 10, // 被 source 中的值替代
y: 20 // 新增来自 source 的值
}
处理 c:

c 只在 source 中存在,直接赋值。最终的 target 为:
{
b: { x: 10, y: 20 },
d: 4,
a: 1,
c: 3
}
最终结果
合并完成后,target 对象的最终结构如下:

{
b: { x: 10, y: 20 },
d: 4,
a: 1,
c: 3
}

prototype是一个类的原型属性,可以通过

 __proto__

来访问每个类的原型属性

也就是说,假设我们要向target类中合并source类中的属性,我们需要保留target中有的属性但source中没有的属性不变,并把target和source中都有的属性换成source中属性的值。而proto是每个类中的私有属性,每个类都有,我们如果merge合并target和source中的proto的值,也就是利用proto修改source的原型的值同时赋值给target类。

如果source类中有一个属性是proto,举例如下

 let source={
a:1,
"__proto__":{
b:2
}
}

let target={
a:2,
}

也就是修改了source类的原型类中的b属性为2

我们通过merge函数将source类和target类合并,这里再把merge函数的代码拿过来

 function merge(target,source){
for (let key in source){
if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}
}
}

我们进行合并操作

由于source和target类中都有a属性,所以把source中的a属性的值赋值给target中的a属性,target类中a属性值变为1

又由于proto属性是每个类中共有的私有属性,所以把source中proto的值赋值给target类,此时target类变为

 {
a:1,
"__proto__":{
b:2
}
}

也就是把target的原型类中的b属性赋值为2,如果target类的的原型类就是object,也就达到了原型链的链头

又因为在原型链中查找属性或方法时,JavaScript 会从当前对象开始,沿着原型链(即 proto 链)向上查找,直到找到相应的属性或方法或直到到达 Object.prototype 的原型(即 null)。如果找不到,则返回 undefined

所以我们只要修改了object类中属性的值,我们就可以在object原型链下面任意类中调用object类中属性的值

举例

 let o1 ={}
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1,o2)
console.log(o1.a, o1.b)//1 2
o3 ={}
console.log(o3.b)

merge修改了o1类prototype原型类中的属性b为2,由于o1类再往上他的原型类就是object类,所以object类中的b属性为2

所以虽然o3类是空的,我们在o3类中调用b属性,javascript没有在o3类中找到b属性,于是顺着原型链往上找,找到了object类中的b,于是输出值 2

(萌新向)对于nodejs原型链污染中merge函数的作用的个人理解的更多相关文章

  1. 【web安全】Nodejs原型链污染分析

    Nodejs原型链污染分析 什么是js原型? 可以将js原型理解为其他OOP语言中的类,但还是有细微区别. 1. function F(){...} 2. var f = new F(); 分析: 1 ...

  2. redpwnctf-web-blueprint-javascript 原型链污染学习总结

    前几天看了redpwn的一道web题,node.js的web,涉及知识点是javascript 原型链污染,以前没咋接触过js,并且这个洞貌似也比较新,因此记录一下学习过程 1.本机node.js环境 ...

  3. 原型链污染(Node.js污染,javasrcipt原型链污染的)

    学习链接: https://www.jianshu.com/p/6e623e9debe3 关于NJS  https://xz.aliyun.com/t/7184 相关题是 GYCTF  ez_expr ...

  4. javascript 原型链污染

    原理①javascript中构造函数就相当于类,并且可以将其实例化 ②javascript的每一个函数都有一个prototype属性,用来指向该构造函数的原型同样的javascript的每一个实例对象 ...

  5. 初探JavaScript原型链污染

    18年p师傅在知识星球出了一些代码审计题目,其中就有一道难度为hard的js题目(Thejs)为原型链污染攻击,而当时我因为太忙了(其实是太菜了,流下了没技术的泪水)并没有认真看过,后续在p师傅写出w ...

  6. js原型链污染详解

    前言 之前打某湖论剑,两道js的题,给我整懵逼了,发现以前都没对js做过多少研究,趁着被毒打了,先研究一波js原型链,未雨绸缪. 基础 protype 首先我们研究js原型链,得搞明白原型是什么,这里 ...

  7. 原型链继承中的prototype、__proto__和constructor的关系

    前不久写了有关原型链中prototype.__proto__和constructor的关系的理解,这篇文章说说在原型链继承中的prototype.__proto__和constructor的关系. 通 ...

  8. 简单粗暴地理解 JavaScript 原型链 (一个充满歪门邪理的理解方法,有助于新手哦!)

    原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...

  9. JavaScript原型链及其污染

    JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...

  10. jacascript 构造函数、原型对象和原型链

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 先梳理一下定义: 我们通常认为 object 是普通对象,function 是函数对象: Function ...

随机推荐

  1. Oracle VM VirtualBox虚拟机安装Centos

    virtualBOx 6.x.x版本跟 virtualBOx 5.x.x 界面已经不一样,但安装步骤还是一样的 镜像下载可以使用下面帖子中的,网易镜像或者阿里云镜像,选取适合自己的镜像 开源镜像站,v ...

  2. 使用Win32控制台实现libevent通信

    libevent版本:libevent-2.0.22-stable 服务端: #include <string.h> #include <errno.h> #include & ...

  3. OpenGL与GLSL各版本对应说明

    OpenGL 4.6 (API Core Profile) (API Compatibility Profile) OpenGL Shading Language 4.60 Specification ...

  4. 「实战篇」开源项目docker化运维部署-借助dockerSwarm搭建集群部署(九)

      为了让学习的知识融汇贯通,目前是把所有的集群都放在了一个虚拟机上,如果这个虚拟机宕机了怎么办?俗话说鸡蛋不要都放在一个篮子里面,把各种集群的节点拆分部署,应该把各种节点分机器部署,多个宿主机,这样 ...

  5. 【Java】网络编程

    InternetAccess类的使用 一.概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信息共享硬件 ...

  6. 【虚拟机】Windows(x86)上部署ARM虚拟机(Ubuntu)

    [虚拟机]Windows(x86)上部署ARM虚拟机(Ubuntu) 零.起因 最近在学嵌入式,这就不得不涉及ARM指令集,但是电脑是x86指令集的,用手机不太方便,买开发板又要等几天--,总之就是要 ...

  7. leetcode每日一题:对角线上的质数

    题目 2614. 对角线上的质数 给你一个下标从 0 开始的二维整数数组 nums . 返回位于 nums 至少一条 对角线 上的最大 质数 .如果任一对角线上均不存在质数,返回 0 . 注意: 如果 ...

  8. idea git建立分支、切换分支、合并分支

    为什么要建立分支 git默认的主分支名字为master,一般团队开发时,都不会在master主分支上修改代码,而是建立新分支,测试完毕后,在将分支的代码合并到master主分支上 2.操作如下: 2. ...

  9. 🧠 Model Context Protocol(MCP)详解:AI 编程新时代的“USB 接口

    目标读者:具备一定编程基础,但尚未涉足 AI 编程的开发者 本文目的:帮助你理解 MCP 的核心概念.技术优势.运作机制,并指导你如何使用 MCP 构建智能体项目. 什么是 MCP? MCP,全称 M ...

  10. github仓库的README文件在线预览视频

    1. 新建一个 issue ,在 issue 里面上传 mp4 视频文件(有限制,不能超过10MB) 上传超过10MB的视频会提示报错 2. 拿到视频文件的上传地址 3. 将这个地址直接贴到 READ ...