zoukankan      html  css  js  c++  java
  • 深浅拷贝

    深浅拷贝是什么:

    理解:简单来说,假设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);
    

    }

  • 相关阅读:
    香港两日游的那些事儿
    香港两日游的那些事儿
    Node.js下的Hello World
    Node.js下的Hello World
    Node.js下的Hello World
    WP SyntaxHighlighter 初探
    WP SyntaxHighlighter 初探
    WP SyntaxHighlighter 初探
    Google的代码高亮-code-prettify
    Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构
  • 原文地址:https://www.cnblogs.com/tyl22/p/14284237.html
Copyright © 2011-2022 走看看