javaScript深拷贝和浅拷贝的简单介绍

目录
  • 基本数据类型
    • 在数据结构当中
  • 引用数据类型
  • 浅拷贝-深拷贝
    • 浅拷贝
    • 浅拷贝小结
  • 深拷贝
  • 结尾
  • 源码地址

在了解深拷贝和浅拷贝之前,我们先梳理一下:

JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型

基本数据类型

数字Number 字符串String 布尔Boolean Null Undefined Symbols BigInt

基本数据类型在内存当中,是存储在栈Stack

在数据结构当中

  • 栈在内存上的分配的空间生命周期很短,当变量使用完毕,方法执行完成就被释放掉,因此在js当中,变量使用完毕之后,基本就被回收了,
  • 有一个场景比较例外,闭包的情况下,变量是始终存在内存当中不被释放.
  • 栈存储具有先进后出,后进先出的特点: 1,2,3,4,5,6 => 6,5,4,3,2,1

引用数据类型

日期Dete,对象Object,数组Array,方法Function, 正则regex,带键的集合:Maps, Sets, WeakMaps, WeakSets

引用数据类型与堆内存heap的一些关系

  • 在JavaScript中,不允许直接访问堆内存中的位置,不能直接操作对象的堆内存空间。
  • 对象的引用地址是存在栈内存中,在我们的日常编码过程中,操作对象的时候,读取对象的存在栈内存的引用地址而不是在堆中的对象,引用类型的值都是通过引用访问。

JavaScript中堆内存和栈内存简易示意图例

下面对于对象的操作,都可以参照上图进行思考

浅拷贝-深拷贝

浅拷贝

只是拷贝了某一层的属性,或者某一层,没有全部拷贝到另外的对象上

let userInfo = {
  name: "zhangsan",
  age: "29",
  say: function () {
    console.log("hello");
  },
  child: [
    {
      name: "zhangsan01",
    },
  ],
};

对象解构,只能拷贝第一层对象

// 对象解构...
let info = { ...userInfo };
info.name = "lisi";
info.child.name = "lisi001";
info.say();

console.log("userInfo", userInfo);
console.log("info", info);

userInfo和info中的child.name都改成了---->"lisi001"

Object.assign() 第一层是深拷贝,二级属性后就是浅拷贝

let info = {};
Object.assign(info, userInfo);
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

JSON.parse(JSON.stringify());

对象可以复制,但是当属性是function时,没有复制到新的对象上,因此在日常的开发过程中,涉及到数组对象,使用JSON.parse(JSON.stringify());还是没问题的

let info = JSON.parse(JSON.stringify(userInfo));
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

for in,第一层可以拷贝,第二层在修改的时候,还是使用的引用地址,前后的对象都发生了更改

let info = {};
for (let key in userInfo) {
  info[key] = userInfo[key];
}
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

浅拷贝小结

以上浅拷贝方法,有些拷贝只能拷贝第一层,有些可以拷贝多层,

但是当属性类型是方法时,还是浅拷贝,

因此我们在开发中,使用浅拷贝,需要注意,同时,出了拷贝function,类似正则,date等数据类型没有一一列举,感兴趣的同学可以自己写一些demo,去校验更为复杂和数据类型更丰富的数据。

深拷贝

所有的属性都拷贝到新的对象上

使用递归遍历每一个属性,在递归遍历的时候,针对每一种数据类型处理和拷贝

lodash深拷贝方法,感兴趣的同学,可以去阅读lodash深拷贝的实现源码

文档地址:深拷贝cloneDeep https://www.lodashjs.com/docs/lodash.cloneDeep

更多方法,有待补充

结尾

当我们操作复杂数据类型的时候,都是在操作栈内存Stack的内存地址,指针指向对象在堆内存heap的数据。

传入的对象是使用对象字面量{}创建的对象还是由构造函数生成的对象

如果对象是由构造函数创建出来的,那么是否要拷贝原型链上的属性

如果要拷贝原型链上的属性,那么如果原型链上存在多个同名的属性,保留哪个

针对的数据类型,属性的数据类型,各自的缺陷,适用的业务场景,自己造轮子or使用原生方法,工具类

到此这篇关于javaScript深拷贝和浅拷贝的文章就介绍到这了,更多相关js深拷贝和浅拷贝内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

源码地址

码云 https://gitee.com/lewyon/vue-note

githup https://github.com/akari16/vue-note

(0)

相关推荐

  • JavaScript数组深拷贝和浅拷贝的两种方法

    例如这个例子: 复制代码 代码如下: var arr = ["One","Two","Three"]; var arrto = arr;arrto[1] = "test";document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,test,Threedocument.writeln("数组的新值

  • 详解JS深拷贝与浅拷贝

    一.预备知识 1.1.JS数据类型 基本数据类型:Boolean.String.Number.null.undefined 引用数据类型:Object.Array.Function.RegExp.Date等 1.2.数据类型的复制 基本数据类型的复制,是按值传递的 var a = 1; var b = a; b = 2; console.log(a); // 1 console.lob(b); // 2 引用数据类型的复制,是按引用传值 var obj1 = { a: 1; b: 2; }; v

  • JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)

    前言 说到深浅拷贝,必须先提到的是JavaScript的数据类型,之前的一篇文章JavaScript基础心法--数据类型说的很清楚了,这里就不多说了. 需要知道的就是一点:JavaScript的数据类型分为基本数据类型和引用数据类型. 对于基本数据类型的拷贝,并没有深浅拷贝的区别,我们所说的深浅拷贝都是对于引用数据类型而言的. 浅拷贝 浅拷贝的意思就是只复制引用,而未复制真正的值. const originArray = [1,2,3,4,5]; const originObj = {a:'a'

  • js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor = { career:'医生' } function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } 使用的时候,这样写

  • JS赋值、浅拷贝和深拷贝(数组和对象的深浅拷贝)实例详解

    本文实例讲述了JS赋值.浅拷贝和深拷贝(数组和对象的深浅拷贝).分享给大家供大家参考,具体如下: 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的.  浅拷贝 只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做浅拷贝(浅复制) 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存.但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象. 赋值和浅拷贝的区别 当我们把一个对象赋值给一个新的变

  • javascript深拷贝和浅拷贝详解

    一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生. 这是为什么呢? 因为如果只是简单的赋值,它只是进行了地址的引用,所以改变一个另一个也会跟着变. var arr = ["One","Two","Three"]; var arrto = arr; arrto[1] = "te

  • JS中实现浅拷贝和深拷贝的代码详解

    (一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. 基本类型值 在JavaScript中基本数据类型有 String , Number , Undefined , Null , Boolean ,在ES6中,又定义了一种新的基本数据类型 Symbol ,所以一共有6种. 基本类型是按值访问的,从一个变量复制基本类型的值到另一个变量后,这两个变量的值

  • javascript深拷贝、浅拷贝和循环引用深入理解

    一.为什么有深拷贝和浅拷贝? 这个要从js中的数据类型说起,js中数据类型分为基本数据类型和引用数据类型. 基本类型值指的是那些保存在栈内存中的简单数据段,即这种值是完全保存在内存中的一个位置.包含Number,String,Boolean,Null,Undefined ,Symbol. 引用类型值指的是那些保存在堆内存中的对象,所以引用类型的值保存的是一个指针,这个指针指向存储在堆中的一个对象.除了上面的 6 种基本数据类型外,剩下的就是引用类型了,统称为 Object 类型.细分的话,有:O

  • JS对象复制(深拷贝和浅拷贝)

    一.浅拷贝 1.Object.assign(target,source,source...) a.可支持多个对象复制 b.如果source和target属性相同 source会复制target的属性 c.target只能为Object对象 var obj = {a:1,b:2} undefined Object.assign({c:3},obj) {c: 3, a: 1, b: 2} obj {a: 1, b: 2} 兼容性写法if(Object.assign){//兼容}else{//不兼容}

  • javaScript深拷贝和浅拷贝的简单介绍

    目录 基本数据类型 在数据结构当中 引用数据类型 浅拷贝-深拷贝 浅拷贝 浅拷贝小结 深拷贝 结尾 源码地址 在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串String 布尔Boolean Null Undefined Symbols BigInt 基本数据类型在内存当中,是存储在栈Stack 在数据结构当中 栈在内存上的分配的空间生命周期很短

  • JavaScript深拷贝和浅拷贝概念与用法实例分析

    本文实例讲述了JavaScript深拷贝和浅拷贝概念与用法.分享给大家供大家参考,具体如下: js中的浅拷贝和深拷贝,只是针对复杂数据类型(Objcet,Array)的复制问题.简单来讲浅拷贝和深拷贝都可以实现在原有对象的基础上再生成一份的作用.但是根据新生成的对象能否影响到原对象可以分为浅拷贝和深拷贝. 概念1:浅拷贝 浅拷贝就是指拷贝引用,新生成的引用和原来的引用都是指向同一个对象的实例,彼此之间的操作会相互影响. 概念2:深拷贝 在堆中重新开辟内存,把原引用对应的对象实例中所有的内容进行拷

  • 老生常谈JavaScript深拷贝与浅拷贝

    目录 1 浅拷贝概念 2 深拷贝概念 3 浅拷贝的实现方式 3.1 Object.assign() 3.2 Array.prototype.concat() 3.3 Array.prototype.slice() 3.4 直接赋值 4 深拷贝的实现方式 4.1 JSON.parse(JSON.stringify()) 4.2 函数库lodash 总结 1 浅拷贝概念 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的. 浅拷贝是创建一个新对象,该对象有着原始对象属性值的一份精确拷

  • JavaScript中的return语句简单介绍

    return语句在js中非常的重要,不仅仅具有返回函数值的功能,还具有一些特殊的用法,下面就结合实例简单介绍一下return语句的作用. 一.用来返回控制和函数结果: 通常情况,return语句对于一个函数是很有必要的,因为往往需要函数在一系列的代码执行后会得到一个期望的返回值,而此值就是通过return语句返回,并且将控制权返回给主调函数. 语法格式: return 表达式 代码实例如下: function add(){ var a=1; var b=2; return a+b; } func

  • Python中深拷贝与浅拷贝的区别介绍

    首先,我们知道 Python 中有6个标准的数据类型,他们又分为可以变和不可变.不可变:Number(数字).String(字符串).Tuple(元组).可以变:List(列表).Dictionary(字典).Set(集合). 浅拷贝 改变原始对象中为可变类型的元素的值,会同时影响拷贝对象.改变原始对象中为不可变类型的元素的值,不会响拷贝对象. 代码演示 import copy #定义一个列表,其中第一个元素是可变类型. list1 = [[1,2], 'fei', 66]; #进行浅copy

  • javascript中的location用法简单介绍

    先前写了一片用window.location.href实现刷新另个框架页面 ,特此我看了一下locaiton的详细用法,对此有点改进,现在我将他整理成js,方便查阅,也贴上和朋友们分享一下,具体如下: 第一.简单介绍一下location属性.用法以及相关示例: Location 包含了关于当前 URL 的信息. 描述 location 对象描述了与一个给定的 Window 对象关联的完整 URL.location 对象的每个属性都描述了 URL 的不同特性. 通常情况下,一个 URL 会有下面的

  • JavaScript中深拷贝与浅拷贝详解

    目录 1 浅拷贝概念 2 深拷贝概念 3 浅拷贝的实现方式 3.1 Object.assign() 3.2 Array.prototype.concat() 3.3 Array.prototype.slice() 3.4 直接赋值 4 深拷贝的实现方式 4.1 JSON.parse(JSON.stringify()) 4.2 函数库lodash 总结 1 浅拷贝概念 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的. 浅拷贝是创建一个新对象,该对象有着原始对象属性值的一份精确拷

  • Java的深拷贝与浅拷贝的几种实现方式

    1.介绍 关于Java的深拷贝和浅拷贝,简单来说就是创建一个和已知对象一模一样的对象.可能日常编码过程中用的不多,但是这是一个面试经常会问的问题,而且了解深拷贝和浅拷贝的原理,对于Java中的所谓值传递或者引用传递将会有更深的理解. 2.浅拷贝 浅拷贝就是获得拷贝对象的引用,而不是正真意义上的拷贝一个对象,例如 A a = new A(); A b = a; 此时引用变量a和b 同时指向了同一个堆中的内存空间,变量b只是复制了实例A的引用地址,并不是重新在堆中开辟了一个新的空间位置,来完整的复制

随机推荐