深浅拷贝

深浅拷贝是什么:

理解:简单来说,假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝;

先理解数据类型:

  • 基本数据类型: undefined、boolean、number、string、null(可直接操作保存在变量中实际的值)
  • 引用数据类型:js除了以上基本数据类型剩下是引用类型,即对象(属性和方法的集合)
基本数据类型
  var name = 'nancy';
  name.toUpperCase();//输出为NANCY
  console.log(name);//输出为nancy
  
  var person = 'nancy';
  person.age = 20;
  person,method = function(){...};
  console.log(person.age);//undefind
  console.log(person.method);//undefind

1.原始的name值是不会发生改变         2.基本类型不可添加属性和方法
基本数据类型的变量标识符和值是存放在栈内存中

赋值:

  var a = 10;
  var b = a;
  a++;
  
  console.log(a);//11
  console.log(b);//10

基本数据类型两变量操作相互不影响

引用数据类型
  var person = {};
  person.age = 20;
  person.sayName = function(){console.log(person.age)};
  person.sayName();//20

  delete person.age;
  person.sayName();//undefind

引用类型的值可以动态改变

  var person1 = {};
  var person2 = {};
  console.log(person1 == person2);//false

引用类型的值同时保存在栈内存和堆内存的对象,这里相等是比较两对象堆内存地址是否相同,显然这里不同

赋值:

  var a = {};//a保存一个空对象实例
  var b = a;//a,b都指向这空实例
  
  a.age = 10;
  console.log(a);//10
  console.log(b);//10

保存在变量中的是对象在堆内存的地址,与基本数据类型数据赋值不同,这里的值实际是一个指向存储在堆内存的一个对象,两变量的指向都在同一个堆内存,因此改变一个值(堆内存中),另一变量的值也发生改变,深拷贝可解决此问题。

深拷贝优点:防止变量全局污染,解决方法如下:

//深、浅拷贝
//数组  slice()  concat()
var arr3 = ['a','b','c'];
var arr4 = arr3;
arr4[1]= 100;
console.log(arr3);
var arr5 = arr3.slice(0);  // var arr5 = arr3.concat();
arr5[1]= 99;
console.log(arr3);

//对象
var o6 = {
    name:'abc',
    age:18,
    arr:[1,2],
    o:{id:1},
    action:function(){

    }
};
var o7 = new Object();  //实际浅拷贝,虽然基本数据类型不会变,但是其引用对象还是会随之改变,深拷贝:所有的类型都不会随之改变
o7.name = o6.name;
o7.age = o6.age;
o7.o = o6.o;
o6.o.id = 'o6ID';
console.log(o7);

//Object.assign()
var ob1 = {a:1,b:2};
var ob2 = {x:1,y:2};
Object.assign(ob1,ob2);
console.log(ob1);//{a:1,b:2,x:1,y:2}
//合并的方法
function fun(o){
    var obj = {};
    Object.assign(obj,o);   ////浅拷贝
    return obj;
};
var ob1 = {a:1,b:2,sub:{id:1}};
var obj10 = fun(ob1);
ob1.a = 'aaaa';
obj10.sub.id = 100; //其方法还是会随之改变,仍然是浅拷贝
console.log(obj10);
console.log(ob1);

//深拷贝(挺好用的方法)   弊端:不支持function
var obj = {
    name: 'sonia',
    age: 18,
    sub:{
        id:1
    },
    action:function(){
        console.log(this.age);
    }
}
var obj2 = JSON.parse(JSON.stringify(obj));
obj.sub.id = 100;
console.log(obj2);
console.log(obj);

//2公共方法
var Animal={
    name: "duobi",
    skin: ["red", "green"],
    child: {
        xxx: "xxx"
    },
    say: function(){
        console.log("I am ", this.name, " skin:", this.skin)
    }
}
function deep(dest, obj){
    var o = dest;
    for (var key in obj) {  
        if (typeof obj[key] === 'object'){   //判断是不是对象(是不是数组或对象)
            //(obj[key].constructor===Array)?[]:{};  //constructor判断类型是数组还是对象
            //var o ={},arr = [];
            //console.log(o.constructor == Object);console.log(arr.constructor == Array);
            o[key] = (obj[key].constructor===Array)?[]:{};
            deep(o[key], obj[key]);
        } else {
            o[key] = obj[key]
        }
    }
    return o;
};
var x = deep({},Animal);
var y = deep({},Animal);
x.child.xxx = 'aaa';
console.log(x);
console.log(y);

}

posted @ 2021-01-15 21:02  奋斗的小树酱tao  阅读(43)  评论(0编辑  收藏  举报