本文共 2866 字,大约阅读时间需要 9 分钟。
浅拷贝 深拷贝
了解基本数据类型基本数据类型有哪些,number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类。number string boolen undefind null symbol bigIndt
复杂的引用数据类型 对象object 数组 function函数等
由于两种数据类型存储不一样,导致拷贝的时候,是有不一样的处理方式的:
基本数据类型:存储在栈内存中 name和val对应存在栈内存中
复杂数据类型:name名字存在栈内存中,值是存于堆内存中,栈内存会提供一个引用地址指向堆内存中的值所以当b=a进行浅拷贝时,如果a中有子类是复杂类型时,其实b复制的a的子类的时候,其实是复制a里面的引用地址,并不是a里面的值,所以当a进行值得修改的时候,a和b指向的是同一个地址,所以b就也受到了影响
// 1. 实现浅克隆
const obj = { name: 'zhangsn', age: '18', sonobj: { name: 'son', age: 8 } } function shallowClone(obj) { let newobj = {} for (const i in obj) { newobj[i] = obj[i] } return newobj } // 如果元数据是基本数据类型的话,浅拷贝下来,两个数据互不影响 // let data = shallowClone(obj) // console.log(data); //age: "18"name: "zhangsn"sonobj: {name: "son", age: 8} // obj.name = 'wangwu' // console.log(obj); //age: "18"name: "wangwu"sonobj: {name: "son", age: 8} // console.log(data); //age: "18"name: "zhangsn"sonobj: {name: "son", age: 8} // let data = shallowClone(obj) // console.log(data); //age: "18"name: "lisi"sonobj: {name: "son", age: 8} // data.name = 'lisi' // console.log(obj); //age: "18"name: "zhangsn"sonobj: {name: "son", age: 8} // console.log(data);//age: "18"name: "lisi"sonobj: {name: "son", age: 8} // 如果元数据是复杂数据类型,就是子类含有复杂数据类型的时候,浅拷贝下来,会互相影响数据,一定要使用深拷贝 // 深拷贝方法一 function deepCopy(obj) { if (typeof obj === 'object') { var result = obj.constructer === Array ? [] : {}; for (let i in obj) { result[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i]; } } else { var result = obj; } return result; } // 深拷贝方法二 // 首先得明白JSON.stringify()与JSON.parse()的作用,针对你的疑问,我们可以这样理解,前者能将一个对象转为json字符串(基本类型),后者能将json字符串还原成一个对象(引用类型)。基本类型拷贝是直接在栈内存新开空间,直接复制一份名-值,两者互不影响。而引用数据类型,比如对象,变量名在栈内存,值在堆内存,拷贝只是拷贝了堆内存提供的指向值的地址,而JSON.stringify()巧就巧在能将一个对象转换成字符串,也就是基本类型,那这里的原理就是先利用JSON.stringify()将对象转变成基本数据类型,然后使用了基本类型的拷贝方式,再利用JSON.parse()将这个字符串还原成一个对象,达到了深拷贝的目的。JSON.stringify()对对象的转换,避开了只拷贝地址指向,无法直接拷贝值本身的问题。 function deepClone(obj) { let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone } let data = deepCopy(obj) console.log(data); //age: "18"name: "zhangsn"sonobj: {name: "son", age: 8} obj.sonobj.name = 'changeson' console.log(obj); //age: "18"name: "zhangsn"sonobj: {name: "changeson", age: 8} console.log(data);//age: "18"name: "zhangsn"sonobj: {name: "son", age: 8}
深拷贝方法二
首先得明白JSON.stringify()与JSON.parse()的作用,针对你的疑问,我们可以这样理解,前者能将一个对象转为json字符串(基本类型),后者能将json字符串还原成一个对象(引用类型)。基本类型拷贝是直接在栈内存新开空间,直接复制一份名-值,两者互不影响。而引用数据类型,比如对象,变量名在栈内存,值在堆内存,拷贝只是拷贝了堆内存提供的指向值的地址,而JSON.stringify()巧就巧在能将一个对象转换成字符串,也就是基本类型,那这里的原理就是先利用JSON.stringify()将对象转变成基本数据类型,然后使用了基本类型的拷贝方式,再利用JSON.parse()将这个字符串还原成一个对象,达到了深拷贝的目的。JSON.stringify()对对象的转换,避开了只拷贝地址指向,无法直接拷贝值本身的问题。转载地址:http://pqwni.baihongyu.com/