ES6深拷贝与浅拷贝
今天小编和大家一起探讨js中深拷贝和浅拷贝,简单一点理解就是,对于引用数据类型,深拷贝是数据引用地址不同,在改变一个数据的时候,不会影响另一个数据。而浅拷贝刚好相反。两个数据引用的是同一个堆内存地址,一个数据改变的时候,会影响另一个相关的数据。
在之前的章节中,小编提起过关于对象的复制的方法,Object.assign(),但是这个方法只是针对对象的浅拷贝。大家也可以关注我的微信公众号,蜗牛全栈。
let target = {} let source = { a:1, b:2 } Object.assign(target,source) console.log(target) // {a:1,b:2}
let target = {} let source = { a:{ b:{ c:1 } }, e:2, f:3 } Object.assign(target,source) console.log(target) // {a:{b:{c:1}},e:2,f:3}
let target = { a:{ b:{ c:1 } }, e:4, f:5, g:6 } let source = { a:{ b:{ c:1 } }, e:2, f:3 } Object.assign(target,source) console.log(target) // {a:{b:{c:1}},e:2,f:3} // 这里面没有将target中的g属性和值
深拷贝(基本数据类型)
let a = 5 let b = a a = 6 console.log(a,b) // 6 5
浅拷贝(对象,两个数据相互影响。一个数据内容改变之后会影响另一个数据)
let obj1 = { name:"lilei", age:18 } let obj2 = obj1 console.log(obj1) // {name:"lilei",age:18} console.log(obj2) // {name:"lilei",age:18} obj1.age = 30 console.log(obj1) // {name:"lilei",age:30} console.log(obj2) // {name:"lilei",age:30}
深拷贝(对象)
方式一:
let obj1 = { name:"lilei", age:18 } let str = JSON.stringify(obj1) let obj2 = JSON.parse(str) console.log(obj1) // {name:"lilei",age:18} console.log(obj2) // {name:"lilei",age:18} obj1.age = 30 console.log(obj1) // {name:"lilei",age:30} console.log(obj2) // {name:"lilei",age:18}
方式二:
// 判断数据类型 let checkType = data => { let t = Object.prototype.toString.call(data).slice(8,-1) return t } // 只考虑对象和数组还有基本数据类型的深拷贝 let deepClone = target => { let targetType = checkType(target) let result if(targetType === "Object"){ result = {} }else if(targetType === "Array"){ result = [] }else{ return target } for(let i in target){ let value = target[i] // 每个属性对应的值 // 兼容引用数据类型中还存在引用数据类型的情况 let valueType = checkType(value) if(valueType === "Object" || valueType === "Array"){ result[i] = deepClone(value) // 递归 }else{ result[i] = value } } return result }
附加:
一、JSON:JSON本质就是字符串,对象键不用引号,JSON需要用引号
JSON.stringify(obj) // 将对象转换成JSON格式字符串 JSON.parse(obj) // 将JSON字符串转换成对象
二、typeof只能判断基本数据类型,不能判断引用数据类型,比如对象和数组,返回的都是Object。可以用以下方式处理
let checkType = data => { let t = Object.prototype.toString.call(data) // let t = Object.prototype.toString.call(data).slice(8,-1) 截取对应数据类型,比如Object和Array console.log(t) } checkType({}) // [Object Object] checkType([]) // [Object Array]