如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
A变B不变:深拷贝 A变B变:浅拷贝
拷贝涉及的概念是js的数据类型:栈堆,基本数据类型与引用数据类型
基本数据类型有哪些,number,string,boolean,null,undefined五类。
引用数据类型(Object类)有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。
深拷贝本身只针对较为复杂的object类型数据,因为基本数据类型的拷贝都不会各自影响,因为拷贝的时候是开辟了一个新的栈来存储。
深拷贝的实现:
1.递归方式,了解一下原理即可
Object 对象具有下列属性:
constructor
对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。
Prototype
对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。
hasOwnProperty(property)
判断对象是否有某个特定的属性。必须用字符串指定该属性。(例o.hasOwnProperty("name"))
function deepClone(obj){ //Array.isArray判断是否是数组,不是则为对象 let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ //判断会否为引用数据类型,如果不是则直接拷贝即可 for(key in obj){ //for in 方法是用来遍历对象中的键的 if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } let a=[1,2,3,4], b=deepClone(a); a[0]=2; console.log(a,b);
2.除了递归,我们还可以借用JSON对象的parse和stringify
JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,而JSON.parse()可以将JSON字符串转为一个对象。
function deepClone(obj){ let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone } let a=[0,1,[2,3],4], b=deepClone(a); a[0]=1; a[2][0]=1; console.log(a,b);
let arr = [1,2,3];
JSON.stringify(arr);//'[1,2,3]'
typeof JSON.stringify(arr);//string
let string = '[1,2,3]';
console.log(JSON.parse(string))//[1,2,3]
console.log(typeof JSON.parse(string))//object
在使用JSON.parse()需要注意一点,由于此方法是将JSON字符串转换成对象,所以你的字符串必须符合JSON格式,即键值都必须使用双引号包裹;
let a = '["1","2"]'; let b = "['1','2']"; console.log(JSON.parse(a));// Array [1,2] console.log(JSON.parse(b));// 报错
JSON.stringify()的几种妙用
1.判断数组是否包含某对象,或者判断对象是否相等。
//判断数组是否包含某对象
let data = [
{name:'echo'},
{name:'听风是风'},
{name:'天子笑'},
],
val = {name:'天子笑'};
JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1;//true
//判断两数组/对象是否相等
let a = [1,2,3],
b = [1,2,3];
JSON.stringify(a) === JSON.stringify(b);//true
2.让localStorage/sessionStorage可以存储对象。
localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储的数据多为对象类型,那么这里我们就可以在存储时利用json.stringify()将对象转为字符串,而在取缓存时,只需配合json.parse()转回对象即可。
//存 function setLocalStorage(key,val){ window.localStorage.setItem(key,JSON.stringify(val)); }; //取 function getLocalStorage(key){ let val = JSON.parse(window.localStorage.getItem(key)); return val; }; //测试 setLocalStorage('demo',[1,2,3]); let a = getLocalStorage('demo');//[1,2,3]