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

    一:首先我们先来看一下js有哪些基础数据类型

    基础类型:undefined,unll,number,string,boolean,symbol

    引用类型:object对象类型(object,array,function,data)

    二:对于这两种类型有几个关键知识点

    基础类型存在于栈中

    引用类型的值是同时保存在栈内存和堆内存中的对象

    javascript的变量的存储方式 栈(stack) 和堆(heap)

    关于栈和堆有几个关键点需要了解

    1 栈(stack)是后进先出,堆(heap)是先进先出。

    2 栈(stack)内存是我们手动分配, 堆(heap)内存是自动分配。

    1 对象和数组的赋值操作

    对象:

    1         let obj1 = {name:'gsq',age:18}
    2         let obj2 = obj1
    3         console.log(obj1.age === obj2.age); //true
    4         obj2.age = 90
    5         console.log(obj1.age === obj2.age); //true 

    我们发现当修改了obj2的age的时候obj1也跟着改变

    对于这种对象赋值,两个对象指向的事同一块内存地址,当对象获取key值然后重新赋值,是可以改变值的,这样可以寻找到对象的指针。如果直接改变值,这样是不可以改变的。因为寻不到地址。

    数组:

    1         let arr1 = [1,2,3,4,5]
    2         let arr2 = arr1
    3         console.log(arr1[0] === arr2[0]) //true
    4         arr2[0] = 1000
    5         console.log(arr1[0] === arr2[0])  //true

    发现也是和对象是一样的,arr1和arr2是这个数组对象的一个堆引用地址,指向的是同一个对象

    好了,以上就是对数据类型基本的认识

    浅拷贝

            修改新变量的值会影响原有的变量的值
            默认情况下引用类型都是浅拷贝
     1         let a = {
     2             "fdf":12,
     3             "fdttf":[1,2,3,45,6],
     4             "fdfdfd":{
     5                 "rere":"rerer",
     6                 "erer":{
     7                     "fdfdffd":122323
     8                 }
     9             }
    10         }
    11         let b = {
    12 
    13         }
    14         //1:使用方法的形式  只能拷贝第一层
    15         // assign方法是将a的所有的值赋值到b中
    16         // Object.assign(b,a)
    17         // console.log(b); //跟a一模一样
    18         // b.fdf = "434545" //修改b的fdf键的值
    19         // console.log(a.fdf) //输出12  ,发现这个2个对象是都有一个独立的内存空间了
    20 
    21         //2:自己实现 只复制一层的浅拷贝
    22         // for(let key in a){
    23         //     b[key] = a[key]
    24         // }
    25         console.log(b);
    26         b.fdf = "fdfdfdfdfdfdfdf"; //修改第一层的基本类型数据
    27         console.log(a.fdf);  //发现,修改后与b无瓜
    28         b.fdttf = "dfsfdsfsdf"  //修改第一层的基本类型数据
    29         console.log(a.fdttf); //发现,修改后与b无瓜
    30         b.fdfdfd.rere = "fdfdfdfdfdfdfdf"; //修改第二层的基本类型数据
    31         console.log(a.fdfdfd.rere)  //发现,修改后与b有瓜
    深拷贝
            修改新变量的值不会影响原有变量的值
            默认情况下基本数据类型都是深拷贝
      
    自己实现的方法
     1         let a = {
     2             "fdf":12,
     3             "fdttf":[1,2,3,45,6],
     4             "fdfdfd":{
     5                 "rere":"rerer",
     6                 "erer":{
     7                     "fdfdffd":122323
     8                 }
     9             }
    10         }
    11         let b = {
    12 
    13         }     
    14         // 封装一个深拷贝的函数
    15         function depCopy(target, source) {
    16             // 1.通过遍历拿到source中所有的属性
    17             for(let key in source){
    18                 // console.log(key);
    19                 // 2.取出当前遍历到的属性对应的取值
    20                 let sourceValue = source[key];
    21                 // console.log(sourceValue);
    22                 // 3.判断当前的取值是否是引用数据类型
    23                 if(sourceValue instanceof Object){
    24                     // console.log(sourceValue.constructor);
    25                     // console.log(new sourceValue.constructor);
    26                     let subTarget = new sourceValue.constructor;
    27                     target[key] = subTarget;
    28                     depCopy(subTarget, sourceValue);
    29                 }else{
    30                     target[key] = sourceValue;
    31                 }
    32             }
    33         }
    34 
    35         depCopy(b,a);
    36         b.fdfdfd.rere = "fdfdfdfdfdfdfdf1323"
    37         console.log(a.fdfdfd.rere === b.fdfdfd.rere); //false
  • 相关阅读:
    Google Chart API 阮一峰的网络日志
    PHP随机函数【上】
    php实现socket推送技术
    javascript变量作用域
    如何使用jqplot描绘一个简单的线形图?
    培训小记
    Google自己的浏览器GoogleChrome
    这大半年的回顾
    一个高手的SQL求工作天数的函数
    关于TSQL中数据库重命名
  • 原文地址:https://www.cnblogs.com/gsq1998/p/12230786.html
Copyright © 2011-2022 走看看