28-02:深浅拷贝的区别和实现

数组的浅拷贝:

如果是数组,我们可以利用数组的一些方法,比如 slice,concat 方法返回一个新数组的特性来实现拷贝,但假如数组嵌套了对象或者数组的话,使用 concat 方法克隆并不完整, 如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化,我们把这种复制引用的拷贝方法称为浅拷贝,

深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也互相分离,修改一个对象的属性,不会影响另一个

如何深拷贝一个数组

1、这里介绍一个技巧,不仅适用于数组还适用于对象!那就是:

var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}] 

var new_arr = JSON.parse( JSON.stringify(arr) ); 

console.log(new_arr); 

原理是 JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串,parse 可以把 JSON 字符串反序列化为一个 js 对象,通过这两个方法,也可以实现对象的深复制。

但是这个方法不能够拷贝函数

浅拷贝的实现:

以上三个方法 concat,slice ,JSON.stringify 都是技巧类,根据实际项目情况选择使用,我们可以思考下如何实现一个对象或数组的浅拷贝,遍历对象,然后把属性和属性值都放在一个新的对象里即可

var shallowCopy = function(obj) { 

// 只拷贝对象 

  if (typeof obj !== 'object') return;

// 根据 obj 的类型判断是新建一个数组还是对象 

  var newObj = obj instanceof Array ? [] : {}; 

// 遍历 obj,并且判断是 obj 的属性才拷贝 

  for (var key in obj) { 

    if (obj.hasOwnProperty(key)) { 

      newObj[key] = obj[key]; 

    }

  }

  return newObj; 

}

深拷贝的实现

那如何实现一个深拷贝呢?说起来也好简单,我们在拷贝的时候判断一下属性值的类型,

如果是对象,我们递归调用深拷贝函数不就好了~

var deepCopy = function(obj) { 

  if (typeof obj !== 'object') return; 

  var newObj = obj instanceof Array ? [] : {}; 

  for (var key in obj) { 

    if (obj.hasOwnProperty(key)) { 

      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; 

    }

  }

  return newObj; 

} 

你可能感兴趣的:(28-02:深浅拷贝的区别和实现)