要说深浅拷贝,首先要看下js的数据类型。
大家都知道js包含基本类型和引用类型。
基本类型:String、Number、Boolean、undefined、null、symbol。
引用类型:Object(Function、Array、Date、RegExp(正则表达式))
基本类型放在栈中,引用类型放在堆中,但是引用类型的地址放在栈中。
基本类型的拷贝:直接b=a赋值就行,本身就互不影响。
引用类型的拷贝:就要区分深浅拷贝了,b=a不是拷贝,只是拷贝了新的地址,他们的指向堆中的对象是同一个,会互相影响的
什么是浅拷贝:
浅拷贝就是只拷贝对象的第一层内容
什么是深拷贝:
深拷贝就是完全拷贝,改变b对象后不会影响到a对象
假设一个对象
let obj1={ a:1, b:{b:2}, c:[1,2,3], d:function(){} }
几种浅拷贝方式:
1.es6剩余参数方式...
//浅拷贝 var obj5={...obj1} console.log(obj1,obj5)
2.es6的Object.assign
var obj6=Object.assign({},obj1) console.log(obj1,obj6)
3.自写方法(新空对象,for...in遍历复制)
function simpleClone(obj){ let newobj={} for(let i in obj){ newobj[i]=obj[i] } return newobj }
说下for..in,这是可以遍历对象和数组的key的函数(对象是遍历key,数组是遍历下标)
实现深拷贝的几种方式:
1.使用jquery的$.extend
let obj2=$.extend(true,{},obj1)
2.使用JSON.parse和JSON.stringify 属于半深拷贝(注意这种方式是不能拷贝对象内的方法的)
var obj4=JSON.parse(JSON.stringify(obj1))
3.深拷贝数组 使用slice(传递下标,从0开始复制,返回新数组)
let arr3=arr.slice(0)
4.深拷贝节点 使用cloneNode,在于是否传参
let p=document.getElementById("d") let cp1=p.cloneNode()//拷贝当前层 let cp2=p.cloneNode(true)//拷贝当前层及子元素
5.递归实现深拷贝对象(重写了Object的原型方法)
Object.prototype.clone=function(){ var copy = (this instanceof Array) ? [] : {}; for (attr in this){ if (!this.hasOwnProperty(attr)) continue;//取是否存在当前key copy[attr] = (typeof this[attr] == "object")?this[attr].clone():this[attr];//是否递归调用 } return copy; } var obj3=obj1.clone() console.log(obj1,obj3)