js 浅拷贝和深拷贝

2021-08-20  本文已影响0人  我家有个王胖胖

js实现深拷贝(深度克隆)

对象通过引用被赋值和拷贝。换句话说,一个变量存储的不是“对象的值”,
而是一个对值的“引用”(内存地址)。
因此,拷贝此类变量或将其作为函数参数传递时,所拷贝的是引用,而不是对象本身。

所有通过被拷贝的引用的操作(如添加、删除属性)都作用在同一个对象上。

为了创建“真正的拷贝”(一个克隆),
我们可以使用 `Object.assign` 来做所谓的“浅拷贝”
(嵌套对象被通过引用进行拷贝)或者使用“深拷贝”函数。

浅克隆(浅拷贝)

在数据类型为引用类型的时候,当你给这个变量赋值,其实是引用这个变量在内存中的地址。如下:

var obj = {name: 'ccc', age: 18}    // 定义一个变量为对象,引用类型
var cloneObj = obj      // 创建一个新变量,并赋值
console.log(cloneObj)   // {name: 'ccc', age: 18}  
console.log(cloneObj === obj)   // true

浅克隆带来的问题:

var obj = {name: 'ccc', age: 18}    // 定义一个变量为对象,引用类型
var cloneObj = obj      // 创建一个新变量,并赋值
console.log(cloneObj)   // {name: 'ccc', age: 18}  
console.log(cloneObj === obj)   // true

obj.name = 'www'
console.log(cloneObj)   // { name: 'www', age: 18 }

我们可以发现,我们修改了obj变量的属性值的时候,cloneObj的属性值也跟着发生了变化。原因是他们虽然是两个变量,但是引用的变量是同一个变量。看下图分析:

image

实现深拷贝的三种方法:
1.通过JSON对象实现深拷贝

function deepClone2(obj) {
  let _obj = JSON.stringify(obj),
  return JSON.parse(_obj);
}

注意: 无法实现对象中方法的深拷贝

image

2. 通过Object.assign()拷贝

注意: 当对象只有一级属性为深拷贝;

当对象中有多级属性时,二级属性后就是浅拷贝

image

3.递归实现深拷贝

 function deepClone(data){
       var type = getType(data);
       var obj;
       if(type === 'array'){
           obj = [];
       } else if(type === 'object'){
           obj = {};
       } else {
           //不再具有下一层次
           return data;
       }
       if(type === 'array'){
           for(var i = 0, len = data.length; i < len; i++){
               obj.push(deepClone(data[i]));
           }
       } else if(type === 'object'){
           for(var key in data){
               obj[key] = deepClone(data[key]);
           }
       }
       return obj;
   }
上一篇下一篇

猜你喜欢

热点阅读