一.数据类型
数据分为基本数据类型和引用数据类型
基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)
引用数据类型(Object[Array属于Object])
基本数据类型的特点:直接存储在栈(stack)中的数据
引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
二.深拷贝与浅拷贝
1.浅拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
1.浅拷贝是按位拷贝对象,它会创建一个新对象,有着原始对象属性值的一份精确拷贝。
2.如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
2.深拷贝
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)
1.拷贝第一层级的对象属性或数组元素
2.递归拷贝所有层级的对象属性和数组元素
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
三.js实现深拷贝和浅拷贝
1.浅拷贝
<script>var obj = {id: 1,name: 'andy',msg: {age: 18,color: ['pink', 'blue']}};var o = {}for (var k in obj) {// k 是属性名 obj[k] 是属性值o[k] = obj[k];}console.log(o);o.msg.age = 20;console.log(obj);// Object.assign(o, obj) // 浅拷贝语法糖// console.log(o);// o.msg.age = 20;// console.log(obj);</script>
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,因此如果修改其中一个对象,另一个也会跟着改变。
2.深拷贝
<script>var obj = {id: 1,name: 'andy',msg: {age: 18},color: ['pink', 'red']};var o = {};// 用递归的方式完成深拷贝// 封装函数function deepCopy(newobj, oldobj) {// 遍历oldobj的属性名for (var k in oldobj) {// 判断属性属于哪种数据类型// 1.获取属性值 oldobj[k]var item = oldobj[k];// 2.判断是否属于数组(因为数组也属于对象,所以必须先判断数组)if (item instanceof Array) {newobj[k] = []; // (1)先给newobj添加一个属性k,同oldobj里的kdeepCopy(newobj[k], item) // (2)再用oldobj[k]赋值给newobj[k]} else if (item instanceof Object) {// 3.判断是否属于对象newobj[k] = {};deepCopy(newobj[k], item)} else {// 4.属于简单数据类型newobj[k] = item}}}deepCopy(o, obj)console.log(o);</script>
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会影响到原对象。
参考: 浅拷贝与深拷贝的区别(详解)_Mark sheng的博客-CSDN博客_浅拷贝深拷贝