首先来看一下以下代码vue
let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:1,b:2,c:3} c[0] = 2 e.a = 2 console.log(d[0]) console.log(f.a)
你会发现,同一个Array或者Object赋值给两个不一样变量时,变量指向的是同一个内存地址,因此就会形成其中一个变量改变属性值,同时改变了另一个变量的对应属性值。数组
而大多数实际项目中,咱们想要的结果是两个变量(初始值相同)互不影响。因此就要使用到 拷贝(分为深浅两种)
浅拷贝只复制一层对象的属性,而深拷贝则递归复制了全部层级。
浅拷贝有效性针对的是单一层级对象 [1,2,3]或者{a:1,b:2}
深拷贝有效性针对的是单层或者多层级对象 [1,2,3]或者{a:1,b:2}或者[1,[1],{a:1}]或者{a:[1],b:{c:2}}
// 数组 let a = [1,2] let b = a.slice() // {} let e = {a:[1],b:{d:1},2} let f = Object.create(e) function shallowCopy (obj) { if (typeof obj === 'object' && obj !== null) { if (Array.isArray(obj)) { return obj.slice() } else { let result = {} Object.keys(obj).forEach((item,i) = > { console.log(i) result[item] = obj[item] }) return result } } else { return obj } }
// 利用JSON(它能正确处理的对象是Number, String, Boolean, Array, 扁平对象) let g = JSON.parse(JSON.stringify(obj)) // 适用于 function deepCopy (obj) { if (typeof obj === 'object' && obj !== null) { let objKeys = Object.keys(obj) let result if (Array.isArray(obj)) { result = [] } else { if (obj.constructor === Object) { result = {} } else { return obj } } objKeys.forEach((item) => { if (typeof obj[item] === 'object' && obj[item] !== null) { switch (obj[item].constructor) { case Array: result[item] = deepCopy(obj[item]) break case Object: result[item] = deepCopy(obj[item]) break case Date: result[item] = new Date(obj[item]) break case RegExp: let attributes = '' attributes += obj[item].global ? 'g' : '' attributes += obj[item].ignoreCase ? 'g' : '' attributes += obj[item].multiline ? 'g' : '' result[item] = new RegExp(obj[item].source, attributes); break default: result[item] = obj[item] break } } else { result[item] = obj[item] } }) return result } else { return obj } }