由于原始值和引用值储存方式的不同,赋值变量时,会出现以下情况
let arr = [1,3,5]
let arrCopy = arr
arr[0] = 999
console.log(arr) //[999,3,5]
console.log(arrCopy) //[999,3,5]
有时我们想要得到一个与原对象/数组完全独立的对象/数组,这就是拷贝。
浅拷贝指的是对只有一层数据而没有嵌套的数据对象进行的拷贝。我们有以下几种方法。
var obj1 = {
name: 'mengyun',
age: 18,
hobby: { play: ['footboll'], read: 'book' },
eat: ['苹果', '香蕉', '菠萝']
}
var obj2 = obj1
function shallowCopy(target) {
let clazz = Object.prototype.toString.call(target).slice(8, -1)
let copy
if (clazz == 'Array') {
copy = []
} else if (clazz == 'Object') {
copy = {}
}
for (var k in target) {
copy[k] = target[k]
}
return copy
}
var obj3 = shallowCopy(obj1)
let obj4 = Object.assign({}, obj3) //es
obj2.name = 'meimei'
obj3.age = '20'
obj2.hobby.play = ['games']
obj3.hobby.read = ['news']
obj3.eat = ['哈密瓜'] // 修改一层引用类型
console.log(obj1) //原对象
console.log(obj2) //直接复制
console.log(obj3) //浅拷贝
console.log(obj4) //ES6
对于只有一层数据的对象,浅拷贝与深拷贝是相同的。但是对于对象嵌套对象的数据来说,普通的拷贝无法将第二层数据成功拷贝,稍后再代码中会看到这种情况。
let obj = {
a: 1,
b: 'hhh',
c: {
test1: 999,
test2: '000'
}
}
let obj1 = Object.assign({}, obj) //浅拷贝
let obj2 = deepCopy(obj) //手写递归深拷贝
let obj3 = JSON.stringify(obj1) //JSON实现深拷贝
obj3 = JSON.parse(obj3)
obj.a = 2
obj.c.test1 = 123
console.log(obj)
console.log(obj1)
console.log(obj2)
console.log(obj3)
function deepCopy(target) {
let clazz = Object.prototype.toString.call(target).slice(8, -1)
let copy
if (clazz == 'Array') {
copy = []
} else if (clazz == 'Object') {
copy = {}
} else {
return target
}
for (var prop in target) {
if (target.hasOwnProperty(prop)) {
copy[prop] = deepCopy(target[prop])
}
}
return copy
}
此外有两种简单的数组拷贝的方法:
let arr = [1, 3, 5, 9]
let arr1 = arr
let arr2 = [...arr]
let arr3 = arr.concat([])
arr[0] = 999
console.log(arr)
console.log(arr1)
console.log(arr2)
console.log(arr3)