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

    一、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 }

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

     
     
     
  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/0314dxj/p/11098049.html
Copyright © 2011-2022 走看看