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

    JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象。

    Undefined 其实是已声明但没有赋值的变量的输出结果,null其实就是一个不存在的对象的结果

    • 对于简单的数据类型
      它们值在占据了内存中固定大小的空间,并被保存在栈内存中。 当一个变量向另一个变量复制基本类型的值时,会创建这个值的副本,还有就是不能给基本类型的值添加属性。

      1
      2
      3
      4
      var a = 1;
      var b = a;
      a.attr = 'long';
      console.log(a.attr) //undefined

      上边代码中a就是简单数据类型(number),b就是a的副本,它们两者都占有不同位置,但相等的内存空间。

    • 对于复杂的数据类型
      复杂的数据类型即引用类型,它的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。

      1
      2
      3
      4
      5
      6
      7
      8
      var obj = {
      name: 'long',
      age: 0
      };
      var obj2 = obj;
      obj2.c = 5;
      console.log(obj); //Oject {name: 'long', age: 0, c: 5}
      console.log(obj2); //Oject {name: 'long', age: 0, c: 5}

    我们可以看到obj赋值给obj2后,当我们更改其中一个对象的属性值,两个对象都发生了改变,究其原因是因为obj和obj2这两个变量都指向同一个指针,赋值是复制了指针,所以当我们改变其中一个值,就会影响另一个变量的值。

    浅拷贝

    其实上边的代码就是浅拷贝,有时候我们只是想备份数组,但是只是简单让它赋给一个变量,改变其中一个,另外一个就紧跟着改变,但很多时候这不是我们想要的。

    1
    2
    3
    4
    5
    6
    7
    8
    var obj = {
    name:'wsscat',
    age:0
    }
    var obj2 = obj;
    obj2['c'] = 5;
    console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
    console.log(obj2);////Object {name: "wsscat", age: 0, c: 5}

    深拷贝

    数组

    对于数组我们可以使用slice()和concat()方法来解决上面的问题。

    • slice

      1
      2
      3
      4
      5
      var arr = ['ge', 'yu', 'long'];
      var arrCopy = arr.slice(0);
      arrCopy[0] = 'gai';
      console.log(arr) // ['ge', 'yu', 'long']
      console.log(arrCopy) // ['gai', 'yu', 'long']
    • concat

      1
      2
      3
      4
      var arr = ['ge', 'yu', 'long'];
      var arrCopy = arr.concat();
      arrCopy[0] = 'gai';
      //console跟上边一样

    对象

    对象我们可以定义一个新的对象并遍历新的属性去实现深拷贝
    原始方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var obj = {
    name: 'geyulong',
    age: 0
    };
    var obj2 = new Object();
    obj2.name = obj.name;
    obj2.age = obj.age;
    obj.name = "gaiyulong";
    console.log(obj); // Object {name: 'geyulong', age: 0}
    console.log(obj2); // Object {name: 'gaiyulong', age: 0}

    当然我们是要封装一个方法来实现深拷贝。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var deepCopy = function(source) {
    var result = {};
    for(var key in source) {
    if(typeof source[key] === 'object') {
    result[key] = deepCopy(source[key])
    } else {
    result[key] = source[key]
    }
    }
    return result;
    }
    var obj2 = deepCopy(obj);

    ShareComments

  • 相关阅读:
    chkdsk磁盘修复命令工具怎么用,怎样运行chkdsk工具修复?
    phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接。您应该检查配置文件中的主机、用户名和密码
    APiCloud真机调试需要注意的几个问题
    QQ个人文件夹中的文件被占用,解决办法
    PHPExcel读取excel文件
    数据挖掘与机器学习
    什么是数据挖掘?
    数据挖掘相关的10个问题
    PhpStorm 快捷键大全 PhpStorm 常用快捷键和配置
    VirtualBox提示:错误,创建一个新任务失败,被召者解决办法
  • 原文地址:https://www.cnblogs.com/libin-1/p/6412091.html
Copyright © 2011-2022 走看看