js

JavaScript 深拷贝和浅拷贝

JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象。

Posted by 刘一凡 on February 17, 2017

JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象。

推荐阅读

Javascript深浅拷贝

深入剖析 JavaScript 的深复制

简单的数据类型

简单的数据类型的至,被保存在栈内存中,当一个变量从另一个变量复制基本类型值时,会创建这个值的副本。

var a = 1;
var b = a;
console.log(a)     // 1
console.log(b)     // 1

b = 2
console.log(a)     // 1
console.log(b)     // 2

上面代码中, a 是简单的数据类型,b 就是 a 的副本,它们占据不同的位置。

复杂的数据类型

复杂的数据类型即引用类型,它们的值保存在堆内存中。保存引用类型值的变量并不是对象本身,而是指向该对象的指针,从一个变量复制另一个变量的引用类型的值,复制的其实都是对象的指针,所以两者指向的是同一个对象。

var person = {
  name: 'lyf',
  year: 22,
}

var person2 = person
person2.name = 'xx'

console.log(person)     // { name: 'xx', year: 22 }
console.log(person2)    // { name: 'xx', year: 22 }

浅拷贝

浅拷贝只是单纯的一个变量复制另一个变量,如果是基本数据类型,这样可以,但是复制引用类型时,得到的结果可能并不是我们想要的。

实际工作中,我们从后台获取到数据,并对数据进行操作,如果单纯使用浅拷贝,可能会出错。

// 比如 我们获取到 data 数据

var data = {
  name: 'xx',
  year: 20
}

// 我们需要对数据进行一些操作,理想状态是通过一个变量 newData 来保存 data,操作 newData
var newData = data

// 操作完成后发现 原来的 data 也变了
newData.year = 22

console.log(data.year)    // 22

###深拷贝

对象

对于上面这种情况,我们可以使用 Object.assign() 来深拷贝对象,或者自己封装深拷贝方法来解决。

var data = {
  name: 'xx',
  year: 20
}

var newData = Object.assign({}, data)

newData.year = 22

console.log(data.year)    // 20

数组

如果数组元素不是对象的话,可以使用 slice() 或者 concat() 方法。

var arr = [1, 2, 3]
var arrCopy = arr.concat()

arrCopy[0] = 0

console.log(arr)        // [1, 2, 3]
console.log(arrCopy)    // [0, 2, 3]

看别人封装的深拷贝

``` var deepCopy = function(source) { var result = {}; for(var key in source) { if(typeof source[key] === ‘object’) { result[key] = deepCopy(source[key]) } else { result[key] = source[key] } } return result; } ``