JS 深浅拷贝

2020-09-20  本文已影响0人  lazy_tomato

START

JS 的数据类型

在说深浅克隆之前,我想提一下JS的数据类型。

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  1. object

为什么要这样区分数据类型呢?

那么为什么要分两种保存方式呢?

知道js变量的保存方式有什么用呢?

题目一

var a = 1

var b = a

console.log('变量a为:', a, "变量b为:", b);  //变量a为: 1 变量b为: 1

a = 88

console.log('变量a为:', a, "变量b为:", b);   //变量a为: 88 变量b为: 1

题目二

var a = {
    name: '张三',
    age: 14
}

var b = a

console.log('变量a为:', a, "变量b为:", b);  
//变量a为: { name: '张三', age: 14 } 变量b为: { name: '张三', age: 14 }

a.name = 'lazy_tomato'

console.log('变量a为:', a, "变量b为:", b);   
//变量a为: { name: 'lazy_tomato', age: 14 } 变量b为: { name: 'lazy_tomato', age: 14 }

浅拷贝

浅拷贝实现方式

  1. 可以通过简单的赋值实现

    类似上面的例子

  2. 利用 Object.assign()实现

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

var obj = { a: { a: "hello", b: 21 } };

var newObj = Object.assign({}, obj);

console.log("obj变量为:", obj, "newObj: ", newObj)
//obj变量为: { a: { a: 'hello', b: 21 } } newObj:  { a: { a: 'hello', b: 21 } }

newObj.a.a = "lazy_tomato";

console.log("obj变量为:", obj, "newObj: ", newObj)
//obj变量为: { a: { a: 'lazy_tomato', b: 21 } } newObj:  { a: { a: 'lazy_tomato', b: 21 } }

注意:当object只有一层的时候,是深拷贝,例如如下:

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);

console.log(obj1, obj2); 
//{ a: 10, b: 20, c: 30 } { a: 10, b: 20, c: 30 }

obj1.b = 100;
console.log(obj1, obj2); 
//{ a: 10, b: 100, c: 30 } { a: 10, b: 20, c: 30 }

深拷贝

深拷贝实现方式

1、对象只有一层的话可以使用上面的:Object.assign()函数
2、转成 JSON 再转回来
var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj1, obj2)  //{ body: { a: 10 } } { body: { a: 10 } }
obj1.body.a = 20;
console.log(obj1, obj2) //{ body: { a: 20 } } { body: { a: 10 } }

缺点

3、递归拷贝
function deepClone(initalObj, finalObj) {    
    var obj = finalObj || {};    
    for (var i in initalObj) {        
      var prop = initalObj[i];        
      if(prop === obj) {            
        continue;
      }        
      if (typeof prop === 'object') {
        obj[i] = (prop.constructor === Array) ? [] : {};            
        arguments.callee(prop, obj[i]);
      } else {
        obj[i] = prop;
      }
    }    
    return obj;
  }

参考的相关网站博客

END

上一篇下一篇

猜你喜欢

热点阅读