javascript中的堆栈、深拷贝和浅拷贝
- 堆、栈
- 堆内存是用来存放引用类型的空间环境(object)
- 而栈内存,是存储基本类型和指定代码的环境(执行上下文)
- 普通变量直接存在栈中执行上下文的变量环境或词法环境中,但是引用类型是把变量名存在栈中,该变量名的值是指向堆中的地址。
- 在对象中的属性名具有唯一性,数字属性名=字符串属性名,但是在测试的时候你会发现,好像所有属性名都会自动转换成字符串,但事实却不是这样,Symbol就是最好的证明。
let a={} let b=Symbol("1"); let c=Symbol("1") a[b]=123; a[c]=123456; console.log(a[b]); console.log(a);
- 克隆拷贝:基本都是对于对象或数组而言,以多维对象为例子,也就是对象嵌套对象
- 浅拷贝
- 只拷贝第一层:对于多重嵌套的对象来说,浅拷贝的意思就是指拷贝第一层,也就是因为对象名只是指向对象再堆中的地址,浅拷贝只是把地址复制一份,而不是重新开辟内存空间。
-
let obj1={name:"chengjunfeng", age:18, love:{ gril:"Mary", sport:"run", Mary:{ age:20, love:"sing" } } } function copy(obj){ let obj2={}; for(let key in obj){//只拷贝第一层 if(!obj.hasOwnProperty(key)) break;//不需要拷贝私有的 obj2[key]=obj[key]; } return obj2; } let obj3=copy(obj1); console.log(obj1); console.log(obj3); //当我修改obj3.love.gril的时候,obj1也会变, obj3.love.gril="Li"; console.log(obj3.love.gril); console.log(obj1.love.gril); //使用ES6中的解构对象也可以直接实现浅拷贝 let obj4={...obj1}; console.log(obj4);
- 深拷贝:把对象中的每一层都进行拷贝,可以采用递归的思路
let obj1={name:"chengjunfeng", age:18, love:{ gril:"Mary", sport:"run", Mary:{ age:20, love:"sing" } } } function deepcopy(obj){ // 递归终止条件 if(typeof obj !=='object') return obj; if(obj===null) return null; if(obj instanceof RegExp) return new RegExp(obj); if(obj instanceof Date) return new Date(obj); let obj2={}; for(let key in obj){ if(obj.hasOwnProperty(key)) obj2[key]=deepcopy(obj[key]); } return obj2; } let obj3=deepcopy(obj1); console.log(obj1); console.log(obj3); //当我修改obj3.love.gril的时候,obj1的不会变, obj3.love.gril="Liiii"; console.log(obj3.love.gril); console.log(obj1.love.gril); //也可使用JSON进行转换;但是JSON.stringify对于日期函数正则会出错 let obj4=JSON.parse(JSON.stringify(obj1)) console.log(obj4);
- 浅拷贝
浪波激泥