首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么将一个对象的值赋给另一个对象的值,然后重新分配原始对象会同时更改这两个对象?

将一个对象的值赋给另一个对象的值,然后重新分配原始对象会同时更改这两个对象的原因是因为在大多数编程语言中,对象的赋值操作实际上是将对象的引用(内存地址)赋给了另一个对象。这意味着两个对象实际上指向了同一块内存空间,它们共享相同的数据。

当我们修改其中一个对象时,由于它们引用同一块内存空间,另一个对象也会受到影响,因为它们实际上是同一个对象的不同引用。这种行为被称为浅拷贝(Shallow Copy)。

举个例子来说明,假设有两个对象A和B,它们的值分别为1和2。当我们执行B = A时,实际上是将A的引用赋给了B,它们指向同一块内存空间。如果我们修改A的值为3,那么B的值也会变为3,因为它们共享相同的数据。

这种行为在某些情况下是有用的,特别是当处理大型对象时,避免了复制整个对象的开销。然而,有时我们可能需要创建一个新的对象并复制原始对象的值,而不是共享相同的数据。这时我们需要进行深拷贝(Deep Copy)操作,确保每个对象都有自己的独立内存空间。

总结起来,将一个对象的值赋给另一个对象的值,然后重新分配原始对象会同时更改这两个对象,是因为对象赋值实际上是将对象的引用赋给了另一个对象,它们共享相同的数据。这种行为被称为浅拷贝。如果需要避免这种共享数据的情况,可以进行深拷贝操作来创建独立的对象。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

const关键字秘密:为什么它不总是像你想象那样

变量名作为标签 下面是完全有效JavaScript程序: 5; 这是另一个: ['apple', 'banana', 'cherry']; 在这两个例子中,我正在创建一些东西。一个数字和一个数组。...重新分配我们标签 当我们使用 let 关键字创建一个变量时,我们能够更改该标签所引用“事物”。 例如,我们可以将我们 fruits 标签指向一个: 这被称为重新分配。...这是另一个例子,使用对象而不是数组。只要标签继续指向相同对象,我们就可以编辑对象键/重新分配变量名称指向新事物)和突mutation (编辑事物内数据)之间存在根本区别。...以一个数字为例: let age = 36; age = 37; 我们应该如何解释这个?我们是 age 标签重新分配一个,还是突变这个数字, 36 编辑为 37 ?...这显然让人感到困惑和无助,这就是为什么在JavaScript中基本类是不可变

37820

JavaScript 是如何工作:JavaScript 共享传递和按传递

EBP 只是存取某时刻 ESP,这个时刻就是进入一个函数内后,cpu 会将ESP EBP,此时就可以通过 EBP 对栈进行操作,比如获取函数参数,局部变量等,实际上使用 ESP 也可以。...我们返回是190,把它了 EAX。 mov ebp+16, eax EAX 是"累加器"(accumulator), 它是很多加法乘法指令缺省寄存器。 然后,恢复所有寄存器。...调用函数之前,调用者参数推入堆栈。因此,可以正确地说在 js 中传递参数是传入一份拷贝。如果被调用函数更改了参数,它不会影响原始,因为它存储在其他地方,它只处理一个副本。...就像我们在汇编代码中看到那样。最初,num1 引用与 n 相同内存地址,因为n被推入堆栈。 然后在创建对象之后, num1 重新分配对象实例内存地址。.../ 这段代码确实影响对象内容 } var a = { key: 'value' }; replace(a); // a 仍然有其原始,它没有被修改 update(a); // a 内容被更改

3.7K41
  • JavaScript中浅拷贝与深拷贝

    浅拷贝是创建一个对象或数组,并将原始对象或数组引用复制给它。这意味着新对象原始对象共享相同内存地址,修改其中一个对象属性或元素也影响另一个对象。...相反,深拷贝是创建一个完全独立对象或数组,新拷贝具有与原始对象或数组相同,但是它们在内存中是彼此独立,相互之间修改不会互相影响。...基本拷贝 下面是一个基本拷贝,新拷贝对象专门开辟一块内存空间——二者类型、都是独立可变,换句话说,他们是通过传递给新对象完成拷贝。...在此示例中,拷贝了一个包含文字对象。由于浅拷贝只会复制原始对象引用而非本身,所以被拷贝对象原始对象共享相同内存空间,即它们也将相同。...尽管这两个对象具有不同变量名称,但它们实际上共享相同内存空间。因此,如果需要更改shallowObj.key1,可以直接修改newObj.key1来获得相同结果。

    28910

    ECMA-262-3深入解析第八章:评估策略

    这是在C++中发生事,当我们传递一个更大结构时,他完全复制到一个内存地址。 注意:除非你明确需要,否则请避免在C++中按传递大对象。使用 const 引用代替。...这个引用副本与形式参数相关联,并且就是形参。 在这种情况,重新分配不会替换原始对象(正如引用策略所做那样)。...仅在C语言中,仍然可以取消引用指针并从外部更改对象。 但是,为指针重新分配一个仅仅只是把它重新绑定到一个内存块中,而不影响旧内存块。仍然可以使用指针修改原始对象属性。...分配仅参数名称重新绑定到新存储器,而保持原始对象不变。 但是正如我们更早提到,此策略通用“按”术语可以在JS程序员中使用-再次表示指针。...一个变量分配给另一个变量只会复制其地址,从而使两个变量都指向相同内存位置。接下来对新分配,将名称与旧地址解除绑定,并将其重新绑定到新地址。

    95410

    Web前端学习 第3章 JavaScript基础教程19 原始类型

    原始类型(或叫类型):数值、字符串、布尔、Null、Undefined 引用类型:对象 原始类型赋值变量,遍历存储是这个本身,而你用类型赋值变量,变量存储一个引用,这个引用会指向内存中这个对象...,但是我们只是obj1name属性赋值为xiaohong,并没有obj2name属性赋值为xiaohong,为什么他们都变成了同一个?...,而这个引用可以指向这个变量本身,所以当我们obj1赋值obj2时候,其实是让这两个变量引用同时指向一个对象,这样当我们改变这个对象时候,两个变量都会有变化。...,在fun内部将参数另一个字符串赋值参数,然后在函数外面输出str,发现str并没有变,然后我们再来看下面这个例子 1 var obj = {name:'xiaoming'}; 2 function...student对象克隆对象这两个对象所有属性都相同,我们修改其中一个对象时候不会影响另一个对象

    36420

    JavaScript 高级程序设计(第 4 版)- 变量、作用域和内存

    # 原始与引用 在把一个变量时,JS引擎必须确定这个原始还是引用原始有6种:Undefined,Null,Boolean,Number,String和Symbol) 原始(primitive...如果使用是new关键字,则JS创建一个Object类型实例,但其行为类似原始 # 复制 在通过变量把一个原始赋值到另一个变量时,原始会被复制到新变量位置。...复制后两个变量独立使用,互不干扰 把引用一个变量另一个变量时,存储在变量中也会被复制到新变量所在位置。但本质是赋值一个指针,指向存储在堆内存中对象。...在函数执行完之后,上下文栈会弹出该函数上下文,控制权返还给之前执行上下文。 上下文中代码在执行时候,创建变量对象一个作用域链。该作用域链决定了各级上下文中代码在访问变量和函数时顺序。...引用计数 对每个都记录他被引用次数。声明变量并给它一个时,这个引用数为1.如果同一个又被另一个变量,那么引用数加1.如果保存对该引用变量被其他覆盖了,那么引用数减1。

    37120

    快速解释如何使用pandasinplace参数

    创建一个示例DataFrame 为了说明inplace用法,我们创建一个示例DataFrame。...因为我们想要检查两个不同变体,所以我们创建原始数据框架两个副本。 df_1 = df.copy() df_2 = df.copy() 下面的代码删除所有缺少行。...当您使用inplace=True时,创建并更改对象,而不是原始数据。如果您希望更新原始数据以反映已删除行,则必须将结果重新分配原始数据中,如下面的代码所示。...是的,最后一行代码等价于下面一行: df_2.dropna(inplace=True) 后者更优雅,并且不创建中间对象然后将其重新分配原始变量。...变量值inplace= True结果 df = df.dropna(inplace=True) 这又是你永远不应该做事情!你只需要将None重新赋值df。

    2.4K20

    聊聊并发编程:final关键字

    1.1 成员变量 成员变量可以分为类变量(static修饰变量)以及实例变量,这两种类型变量初值时机是不同,类变量可以在声明变量时候直接初值或者在静态代码块中类变量初值,实例变量可以在声明变量时候实例变量初值...扩展思考,为什么String类为什么是final?先看下源码 final修饰String,代表了String不可继承性,final修饰char[]代表了被存储数据不可更改性。...但如果字符串是可变,那么字符串池将不能实现,因为这样的话,如果变量改变了它,那么其它指向这个变量一起改变。...在构造函数内对一个final域写入,与随后把这个被构造对象引用赋值一个引用变量,这两个操作之间不能重排序。...对于引用类型,写final域重排序规则对编译器和处理器增加了如下约束:在构造函数内对一个final引用对象成员域写入,与随后在构造函数外把这个被构造对象引用赋值一个引用变量,这两个操作之间不能重排序

    17130

    Java中传递与引用传递

    在本文中,我们深入探讨什么是传递和引用传递,以及为什么Java中只有传递这一问题。 什么是传递? 传递是一种数据传递方式,它是数据副本传递给方法或函数。...当我们一个变量传递给一个方法时,方法接收到原始数据副本,而不是原始数据本身。这意味着在方法内部对参数修改不会影响到原始数据。...modifyValue方法,它接受一个整数参数value,然后value修改为20。...引用传递是一种数据传递方式,它是数据引用或地址传递给方法或函数。这意味着在方法内部对参数修改影响到原始数据。...方法接收到是引用副本,而不是原始引用本身。这意味着在方法内部,如果我们参数重新分配一个对象原始引用不会受到影响。

    32550

    浅习一波JavaScript高级程序设计(第4版)p4

    于是乎,借着更文契机,本瓜开启一个小系列,带你重看一遍高级程序设计4(先前只是跳着跳着看),抽取精华,用最简单的话解释核心点、尽量把握全局、快速过一遍同时,记录与工友们分享~~ 正文 第四章:变量...首先讲到 ECMAScript 变量最大两个特点:原始和引用 当我们在把一个变量时,JavaScript 引擎必须确定这个原始还是引用。...原始有 6 个,前文提过:Undefined、Null、Boolean、Number、String 和 Symbol,保存原始变量是按(byvalue)访问; 而引用则是对象,在操作对象时...这里理解起来确实有点麻烦 QAQ 记住: 函数外会被复制到函数内部参数中,就像从一个变量复制到另一个变量一样;如果是原始,那么就跟原始变量复制一样,如果是引用,那么就跟引用变量复制一样...如果同一个又被另一个变量,那么引用数加 1。 类似地,如果保存对该引用变量被其他覆盖了,那么引用数减 1。

    33730

    Android多线程编程__同步

    而解决这种问题办法通常是当线程A调用修改对象方法时,我们就交给它一把锁,等他处理完后在把锁另一个要调用这个方法线程。 重入锁和条件对象 synchronized 关键字提供了锁以及相关条件。...语句2虽说很短,但他包含了两个操作,它先读取x,在x写入工作内存。读取x以及x写入工作内存这两个操作单拿出来都是原子性操作,但是合起来就不是原子性操作了。...语句3包含3个操作: 读取x,对x进行+1,向工作内存写入新。 所以,当一个语句包含多个操作时,就不是原子性操作,只有简单读取和赋值(数字某个变量)才是原子性操作。...假如某个时刻变量inc为9,线程1对变量进行自增操作,线程1先读取了变量inc原始然后线程1被阻塞了。...之后线程2对变量进行自增操作,线程2也去读取变量inc原始然后进行加1操作,并把10写入工作内存,最后写入主存。

    52720

    C#基础知识系列三(类和结构体、String和StringBuilder、equals和==)

    例如,可以创建 StringBuilder 类带有字符串“Hello”(长度为 5)一个新实例,同时可以指定该对象最大容量为 25。...如果 Length 属性设置为大于 Capacity 属性,则自动 Capacity 属性更改为与 Length 属性相同。...这是因为系统并没有字符串b分配内存,只是"aa"指向了b。所以a和b指向是同一个字符串(字符串在这种赋值情况下做了内存优化)。...对于p1和p2,也是内存中两个不同对象,所以在内存中地址肯定不相同,故p1==p2返回false,又因为p1和p2又是对不同对象引用,所以p1.equals(p2)返回false。...对于p3和p4,p4=p3,p3将对对象引用了p4,p3和p4是对同一个对象引用,所以两个比较都返回true。

    50940

    Java并发关键字-final

    针对这两种类型变量初值时机是不同,类变量可以在声明变量时候直接初值或者在静态代码块中类变量初值。而实例变量可以在声明变量时候实例变量初值,在非静态初始化块中以及构造器中初值。...现在我们来这几种情况归纳整理一下: 类变量:必须要在静态初始化块中指定初始或者声明该类变量时指定初始,而且只能在这两个地方之一进行指定; 实例变量:必要要在非静态初始化块,声明该实例变量或者在构造器中指定初始...读final域重排序规则 读final域重排序规则为:在一个线程中,初次读对象引用和初次读该对象包含final域,JMM禁止这两个操作重排序。...由于一个final域引用对象成员域写入不能与随后这个被构造出来对象引用变量重排序,因此2和3不能重排序。...引用数据类型: 额外增加约束:禁止在构造函数对一个final修饰对象成员域写入与随后这个被构造对象引用赋值引用变量 重排序 final实现原理 上面我们提到过,写final域会要求编译器在

    69330

    JS基础知识总结(二):浅拷贝与深拷贝

    Object.assign()只会拷贝所有的属性到新对象中,如果属性是基本类型,则修改其中一个对象,不会影响另一个。而如果属性对象的话,拷贝对象引用,而不是对象本身。...此方法不会更改现有数组,而是返回一个新数组。注意这里分两种情况: (1)对象引用(而不是实际对象):concat将对象引用复制到新数组中。原始数组和新数组都引用相同对象。...也就是说,如果引用对象被修改,则更改对于新数组和原始数组都是可见。这包括也是数组数组参数元素。...原始数组不会被改变。 也分两种情况: (1)如果该元素是个对象引用(不是实际对象),slice 拷贝这个对象引用到新数组里。两个对象引用都引用了同一个对象。...,并没有创建一个对象,而是把原对象在栈中地址(而非栈中数据)了新对象,即是原对象在栈中地址,原对象和新对象指向是同一个地址。

    2.8K362

    看尤雨溪说:为什么Vue3 中应该使用 Ref 而不是 Reactive?

    ❌ 在 和 使用方式不同(在 中要使用 .value) ❌ 重新分配一个对象丢失响应性 ✅ 重新分配一个对象不会失去响应 能直接访问属性...赋值 reactive 一个整个对象或 reactive 对象 赋值一个普通对象 let state = reactive({ count: 0 }) // 这个赋值导致 state 失去响应 state... reactive 对象属性赋值变量(断开连接/深拷贝) 这种操作类似于深拷贝,不再共享同一内存地址,而是只是字面量赋值,对该变量赋值不会影响原来对象属性。...1, b: 2, c: 3 }) onMounted(() => { // 回显成功 state.value = { a: 11, b: 22, c: 333 } }) 响应式对象字面量一整个普通对象或...另外,说使用 Object.assign 为什么可以更新模板: Object.assign 解释是这样:如果目标对象与源对象具有相同键(属性名),则目标对象属性将被源对象属性覆盖,后面的源对象属性类似地覆盖前面的源对象同名属性

    3K20

    尤雨溪说:为什么Vue3 中应该使用 Ref 而不是 Reactive?

    ❌ 在 和 使用方式不同(在 中要使用 .value) ❌ 重新分配一个对象丢失响应性 ✅ 重新分配一个对象不会失去响应 能直接访问属性...赋值 reactive 一个整个对象或 reactive 对象 赋值一个普通对象 let state = reactive({ count: 0 }) // 这个赋值导致 state 失去响应 state... reactive 对象属性赋值变量(断开连接/深拷贝) 这种操作类似于深拷贝,不再共享同一内存地址,而是只是字面量赋值,对该变量赋值不会影响原来对象属性。...1, b: 2, c: 3 }) onMounted(() => { // 回显成功 state.value = { a: 11, b: 22, c: 333 } }) 响应式对象字面量一整个普通对象或...另外,说使用 Object.assign 为什么可以更新模板: Object.assign 解释是这样:如果目标对象与源对象具有相同键(属性名),则目标对象属性将被源对象属性覆盖,后面的源对象属性类似地覆盖前面的源对象同名属性

    86610

    成员方法传参机制

    2)调用AA对象swap方法, a = 10,b = 20,传给 swap 方法中a和b。 3)在方法中,先输出了一遍a和b原本然后进行了交换,此时在方法中a和b已经互换了。...main方法中数组是一样,可能有小伙伴就要问了,不是说两个方法指向不同内存吗,为什么test100方法中更改数组main方法中也会改变?...流程分析: 1)数组arr三个 1, 2, 3,此时会在堆中新开一个地址来存放,也就是堆中0x0011空间。...3)然后在方法test100中遍历数组进行输出,因为此方法指向内存空间0x0011已经进行了更改,所以输出 200,2,3。...3)在copyPerson方法中创建一个对象p2,p属性p2,此时p和p2属性中相等。 4)返回p2对象,在main方法中用p2接收。

    59410

    【JS】347- 理解JavaScript中变量、范围和提升

    变量也可以重新分配,并给定一个。下面的简化示例演示了如何密码存储到变量中,然后进行更新。...这是一种一个单词小写,然后后面每个单词一个字母大写,中间没有空格做法。除了一些例外,大多数非常量变量都遵循这种约定。使用const关键字声明常量变量名称通常都是大写。...//初始化一个全局变量 var creature = "wolf"; 我们知道变量可以重新分配。使用局部作用域,我们实际上可以创建与外部作用域中变量同名新变量,而无需更改重新分配原始。...在下面的示例中,我们创建一个全局species变量。函数内部是一个具有相同名称局部变量。通过将它们发送到控制台,我们可以看到变量如何根据范围而不同,并且原始不会更改。...因为不能重新分配const,所以需要同时声明和初始化它们,否则也抛出错误。

    1.8K10
    领券