我想问下什么是单拷贝,什么是多拷贝? | 您所在的位置:网站首页 › kwgt复制 › 我想问下什么是单拷贝,什么是多拷贝? |
一、首先先来复习一下javascript中的数据类型: 基本数据类型:string number boolean undefined null symbol 引用数据类型:Function Array Object 在javascript中声明基本类型的变量时会保存在栈(stack)中,声明引用类型的变量时会保存在堆中,同时会在栈中保存一个引用地址指向堆内存。如下图 var a = "小明" //String var b = 123 //Number var c = {name :"小红"} //Object var d = [1,2,3,4] //Array function str(){} //Function以上声明了 变量 a、b、c、d、str函数,由于a和b都是基本数据类型所以在栈中申请了内存空间,变量名为a和b。c和d是引用数据类型所以在堆中申请存放空间,在栈中申请存放具体地址并且这个地址指向堆内存中的具体值。 二、基本数据类型和引用数据类型在赋值(拷贝)时内存的变化 1.基本数据类型 var a = "小明" var b = a console.log(b) //小明2,引用数据类型 var arr1 = [1,2,3] var arr2 = arr1 console.log(arr2) //[1,2,3]如果arr1[0]发生改变那么arr2[0]的值也会发生改变,因为arr1和arr2保存着相同的地址,都是指向同一个数据。所以基于上面的代码我们给arr1[0]的值赋值为10,看内存的变化: 为什么会发生这样的变化呢。接下来就会讲到浅拷贝和深拷贝。 三、浅拷贝和深拷贝 浅拷贝和深拷贝中所谓的拷贝就是赋值,把一个变量赋值给另一个变量,就是把变量的内容进行拷贝。把一个对象的值赋给另一个对象,就是把一个对象拷贝一份。 1.基本数据类型 基本数据类型赋值时赋的事数据,所以不存在深拷贝和浅拷贝的问题。 如: var n = 1 var m = n //此时n,m的值都是1 console.log(n) //1 console.log(m) //1 //如果改变n的值(n = 2) m的值不会改变2.引用数据类型 引用数据类型赋值时,赋的值地址(既引用类型变量在内存中保存的值)。 例: var arr1 = [1,2,3,4] var arr2 = arr1 //这是一个浅拷贝 console.log(arr1,"arr1") console.log(arr2,"arr2")如果改变arr2[0] = 10, 那么arr1[0]也是等于10 原因是arr1和arr2栈内存地址是一样的,并且指向堆内存中同一个值。上面的第二点钟第二点图例可以看出来。 这就是一个简单的浅拷贝,因为arr1的地址拷贝了一份给了arr2,并没有把arr1的数据拷贝一份。 3.用一个 对象来演示浅拷贝和深拷贝 首先我们定义一个json对象 var person = { "name":"小明", "age":13, "hobby":new Array("唱歌","跳舞","打球") //这是引用数据类型 } console.log(person)内存图 把对象person 赋值给 person1 var person = { "name":"小明", "age":13, "hobby":new Array("唱歌","跳舞","打球") //这是引用数据类型 } var person1 = person person1.hobby[0] = "写歌" console.log(person) console.log(person1)因为引用数据类型指向的是同一个堆内存中的值这就是一个浅拷贝。 var person1 = {} var person = { "name":"小明", "age":13, "hobby":new Array("唱歌","跳舞","打球") //这是引用数据类型 } for(let key in person){ if(typeof person[key] == "object"){ person1[key] = [] //给对象person1 赋值一个空数组 for(let i in person[key]){ person1[key][i] = person[key][i] } }else{ person1[key] = person[key]; } } person1.hobby[0] = "写歌" console.log(person1) console.log(person)在控制台打印出来的的只有person1.hobby[0]变成了“写歌” 内存图 常用的浅拷贝 1.object.assign object.assign 的语法为:Object.assign(target, …sources) 2.扩展运算符方式 扩展运算符的语法为:let cloneObj = { …obj }; 3.slice 拷贝数组 slice 的语法为:arr.slice(begin, end); 等等...... 常用的深拷贝 JSON.stringify 把一个对象序列化成为 JSON 的字符串,并将对象里面的内容转换成字符串,最后再用 JSON.parse() 的方法将JSON 字符串生成一个新的对象。 还有很多方法,还请各位“知乎er”自寻查找 |
CopyRight 2018-2019 实验室设备网 版权所有 |