看到了从内存空间来看数据类在内存中存在情况 下面开始卖弄下js 深浅拷贝
浅拷贝
上篇了解到 基本类型拷贝 其实就是在栈中新开辟了一块空间 原对象 跟拷贝出的对象是两个互相独立的东西 这也就是说基本类型深浅都是一样的 深浅拷贝相对引用类型var a = { key1: '123', key2: [4,5] } console.log(a) //key1:123 key2: 数组 function copy (a) { var obj = {} for (var i in a) { obj[i] = a[i] } return obj } var b = copy(a) //这里栈内存中开辟了两个空间 a b 这里存放了对象的变量标识 跟 值(是引用类型就是指针) console.log(b.key1) // 123 这个a b 指针指向同一块堆内存 key1 value值是123 b.key3 = '333' console.log(b.key3) //333 console.log(a.key3) //undefined 这个是key3是一个基本数据类型在 栈中b变量对象中值添加一个key3 并没有通过指针 a b 相互独立 所以a是访问不到的 b.key2.push(8) console.log(b)// 这里去操作b 在堆内存的key2属性 因为a b 都是同一个堆存储 所以 a b 都可以看到 key2数组中添加了一个8复制代码
数据结构
上面出现一个问题就是 a 拷贝到b 在b中的操作引用类型 就会导致a也会改变 因为指针指向同一块堆内存
但是改变b中基本数据类型 并不会引起a 的改变 在a中是访问不到的 因为a b 基本数据类型是放在栈内存中 是相互独立互不影响的所以深拷贝就出现了
深拷贝
如果对象属性值类型是引用类型的话 只会传址(指针) 就会影响原对象 那现在就要 把原对象中属性为引用类型的 要循环的赋给 其他对象var a = { key1: '123', key2: [4,5] } function deepcopy (a, b){ var b =b || {} for (var i in a) { if (typeof a[i] === 'object') { //判断属性key2 是否对象 b[i] = (a[i].__proto__.constructor == Array) ? []: {} deepcopy(a[i], b[i]) //递归 } else { b[i] = a[i] } } return b } var b = {} deepcopy(a,b) console.log(b) //{key1: "123", key2: Array(2)} console.log(a) //{key1: "123", key2: Array(2)} a.key3 = '333' console.log(a) //{key1: "123", key2: Array(2), key3: '333'} console.log(b) //{key1: "123", key2: Array(2)} 基本数据类型a 中添加了个key3 这也看不出啥 基本类型在栈中 不会影响到b b.key2.push('44') console.log(a) //{key1: "123", key2: Array(2), key3: '333'} console.log(b) //{key1: "123", key2: Array(3)} 这样在b 中添加了 对a 没有了影响 基本数据类型是没有影响的 引用类型感觉一个一个给拆出来弄成了栈存 不是通过指针指向堆存复制代码
好了 有错误的希望给指出
参考链接: