javascript中浅拷贝与深拷贝。

时间:2021-08-18 19:52:58

一、JS的基本数据类型

  • 基本数据类型:String,Boolean,Number,Undefined,Null;
  • 引用数据类型:Object(Array,Date,RegExp,Function);
  • 基本数据类型和引用数据类型的区别:
  1. 保存位置不同:基本数据类型保存在栈内存中,引用数据类型保存在堆内存中;
  2. 基本数据类型使用typeof可以返回其基本数据类型,但是NULL类型会返回object,因此null值表示一个空对象指针;引用数据类型使用typeof会返回object,此时需要使用instanceof来检测引用数据类型;
  3. 定义引用数据类型需要使用new操作符,后面再跟一个构造函数来创建;

    1)使用new操作符创建对象;

      var obj1 = new Object();       obj1.a = 1; 

    2)使用对象字面量表示法创建对象;

      var obj1 = {        a: 1       } 

    3)可以通过点表示法访问对象的属性,也可以使用方括号表示法来访问对象的属性;

  4.基本类型与引用类型最大的区别实际就是传值与传址的区别:

    1)值传递:基本类型采用的是值传递。 
    2)地址传递:引用类型则是地址传递,将存放在栈内存中的地址赋值给接收的变量。

二、js中堆内存和栈内存
 
  栈(stack):栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。(基本类型:String,Number,Boolean,Null,Undefined);
  堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。(引用类型:Function,Array,Object);
 
  区别:
    栈:所有在方法中定义的变量都是放在栈内存中,随着方法的执行结束,这个方法的内存栈也自然销毁。
    优点:存取速度比堆快,仅次于直接位于CPU中的寄存器,数据可以共享;
    缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
    堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区。   
 
三、浅拷贝与深拷贝 
  1. 浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,指向同一个内存,只是拷贝了引用的地址,当改对象发生改变,拷贝的对象也随之发生改变。
  2. 深拷贝:深拷贝就是完完整整的将一个对象从内存中拷贝一份出来,拷贝出来的内存和原对象内存的指向都是不同的,修改不会相互影响。
四、深拷贝的实现方式(浅拷贝就不说了)
  数组深拷贝:

  1. for循环: 

    let arr1 = [1,2,3];
    let arr2 = [];
    for(let i=0,length=arr.length;i<length;i++){
      arr2 .push(arr[i]);
    }

  2..es6中扩展运算符:

    let arr1 = [1,2,3];

     let [...arr2] = arr1;

  3.Array.from :

    let arr1 = [1,2,3];

     let arr2 = Array.from(arr1);

  注意:slice()和concat()都并非深拷贝。

 

  对象的深拷贝:

  1.for循环:

    let obj1={count:1,name:'grace',age:1};

    let obj2 = copyObj(obj){

       let res = {};

      for(let key in obj){

        res[key]=obj[key];

      } return res;

     }

  2.利用JSON:

    let obj1={count:1,name:'grace',age:1};

    let obj2 = JSON.parse(JSON.stringify(obj1));

  3.扩展运算符:

    let obj1={count:1,name:'grace',age:1};

    let {...obj2} = obj1;

  4.Object.assign()实现浅拷贝及一层的深拷贝

    const target = { a: 1, b: 2 };
    const source = { b: 4, c: 5 };

    const returnedTarget = Object.assign(target, source);

    console.log(target);
      // expected output: Object { a: 1, b: 4, c: 5 }

    console.log(returnedTarget);

      // expected output: Object { a: 1, b: 4, c: 5 }

写的不足,欢迎大家吐槽!